What I have understood is to define variables inside init magic method. I did but the next method is not reading it.
Any help?
class Foo:
var = 9
def __init__(self, a, b):
self.i = a
self.j = b
def add(self, a, b):
print a+b
bar = Foo(5, 5) # create object
print bar.var # access class variable
o/p:
9
Why does it not print
10
9
If you want to run the code inside add, you must call it.
bar = Foo(5, 5) # create object
bar.add(5,5)
print bar.var # access class variable
You called the variables self.i and self.j, not a and b, so that's how you need to refer to them. add() should be defined like this:
def add(self):
print self.i+self.j
Related
A noob confused question,
I have two methods in a class as :
from example import sample2
class sample1:
def m1():
a='apple'
b='ball'
return sample2.m3(a,b)
def m2():
a='ant'
b='bat'
c='cat'
return sample2.m3(a,b,c)
in example.py:
class sample2:
def m3("here I want to access any `a`,`b`,`c` of respective m1 and m2"):
.....
Iam sorry if this question makes no sense, but when I try to access only this as:
class sample1:
def m1():
a='apple'
b='ball'
return sample2.m3(a,b)
in example.py:
class sample2:
def m3(a,b):
print(a)
a has value apple, so similar way why can't I access any value of a,b,c from that particular m1,m2 returned ?
This is how you use decorators. More information how decorator works can be found in for example here: https://www.datacamp.com/community/tutorials/decorators-python
I would suggest you to first try to better understand concept of class and objects. Example tutorial: https://www.w3schools.com/python/python_classes.asp
This post could also help you to understand how staticmethod decorator works - What is the difference between #staticmethod and #classmethod?
from example import sample2
class sample1:
#staticmethod
def m1():
a='apple'
b='ball'
return sample2.m3(a,b)
#staticmethod
def m2():
a='ant'
b='bat'
c='cat'
return sample2.m3(a,b,c)
example.py file with explanation:
class sample2:
#staticmethod
def m3(a, b, c=None): # it works exactly the same as m3 function that is outside the class
print(a)
# this can be used without creating an object of sample2 class, example:
# sample2.m3(a="apple, b="ball")
def m3_method(self, a, b): # this one requires object on which it can be called
print(a)
# you have access to sample2 class object via self parameter, example of code:
# sample2_object = sample2() # you create object of sample2 class here
# sample2_object.m3_method(a="apple", b="ball") # you call m3_method on sample2_object here
def m3(a, b, c=None): # default value of c is add so you can either call it with 2 or 3 arguments
# example calls:
# m3("a", "b")
# m3("a", "b", "c")
print(a)
You should be able to run this code and I think it gives you an idea how Python classes can be used.
Variables in Python always apply to a specific scope, such as a class, function or closure. Python uses lexical scoping, which means scopes are only connected by nesting in the source code. Most importantly, variables in different scopes are not connected at all.
When you "pass a variable" to a function, you are actually passing only the value around. The variable does not exist in other functions (unless they are nested) nor the surrounding scope.
def nested(a):
a = 3
print('a =', a) # a = 3
def parent():
a = 4
nested(a)
print('a =', a) # a = 4
parent()
print(a) # NameError: name 'a' is not defined
Functions should primarily exchange data by calling with input and returning results:
def nested(a): # receive input
a = 3
print('a =', a) # a = 3
return a # return output
def parent():
a = 4
a = nested(a) # replace a with result of nested(a)
print('a =', a) # a = 3
parent()
Note that only values are passed in and returned. The above could would behave exactly the same if you renamed a in either function.
When working with class instances, the instance itself works as a namespace (similar to a scope). Methods of that instance can exchange data by modifying attributes of the instance. The instance is always passed as the first argument to methods:
class Example():
"""An example for setting attributes on an instance"""
def __init__(self):
self.a = 0
def nested(self):
self.a = 3
print('self.a =', self.a) # self.a = 3
def parent(self):
self.a = 4
print('self.a =', self.a) # self.a = 4
self._nested()
print('self.a =', self.a) # self.a = 3
instance = Example()
print(instance.a) # 0
instance.parent() # self.a = 4
# self.a = 3
To exchange data between objects, methods should also primarily exchange data by calling with input and returning results :
class Example():
"""An example for setting attributes on an instance"""
def __init__(self, a):
self.a = a
def multiply(self, value):
return self.a * value
instance = Example(6)
print(instance.multiply(10)) # 60
I'd like to create a class that has 2 input attributes and 1 output attribute such that whenever one of the input attributes are modified the output attribute is modified automatically
I've tried defining the attributes as instance variables within and outside the constructor function but in either case, after instantiating the object, the output attribute remains fixed at the value set at the moment of instantiation
class Example():
def __init__(self,n):
self.name=n
inA=1
inB=1
if inA==1 and inB==1:
outA=1
else:
outA=0
when instantiated outA is set to 1 as expected
but if I try to update:
object.inA=0
object.outA remains 1 whereas I need it to be updated to 0
Trying to avoid the use of functions if possible. New to python and OOP so sorry if this question is nonsensical or has an obvious answer
If you want instance attributes that depend on other instance attributes, properties are the way to go.
class Example:
def __init__(self, n):
self.name = n
self.inA = 1
self.inB = 1
#property
def outA(self):
return self.inA and self.inB
You access outA like a regular instance attribute, obj.outA.
>>> my_obj = Example("example")
>>> my_obj.outA
1
Changing the attributes inA and inB affect outA.
>>> my_obj.inA = 0
>>> my_obj.outA
0
You can create a function in the class and some other minor changes:
class Example():
def __init__(self,n):
self.name=n
self.inA=1
self.inB=1
def f(self):
if self.inA==1 and self.inB==1:
self.outA=1
else:
self.outA=0
To call it:
a = Example('foo')
a.inA = 0
a.f()
print(a.outA)
Output:
0
As you can see, taking out:
a.f()
line would make it give an error:
AttributeError: 'Example' object has no attribute 'outA'
Do you want it to return your output?
Expanding on U9-Forward's answer:
class Example():
def __init__(self,n):
self.name = n
self.inA = 1
self.inB = 1
def f(self):
return self.inA and self.inB
I have a class Foo which is instantiated an indefinite number of times during my program sequence. Like so:
def main():
f = Foo()
while f.run():
del f
f = Foo()
with run() being a method that runs an decisive condition for keeping the program alive.
Now, my Foo class creates on its __init__ method two objects a and b:
Foo class
class Foo:
def __init__(self):
a = A()
b = B(a.var)
I'm looking for a way to a being declared only at the first Foo instantiation and use that same first-instantiated a at the other Foo instantiations.
Problem arises because b depends on a. I thought about a couple solutions - from playing with __new__ and __init__ to override __del__ and global variable as cache - but none of them worked.
note: A needs to be at the same module as Foo
Maybe using a class variable?
class Foo:
a = None
def __init__(self):
if not Foo.a:
Foo.a = A()
b = B(Foo.a.var)
And function B needs to check whether a is None.
If I understand you correctly, you should be able to just make a a class variable.
class Foo:
a = A()
def __init__(self):
b = B(Foo.a.var)
I'm afraid some of your requirements will make Foo extremely difficult to test. Instead, I would suggest that you move some of the dependencies from your constructor to a start class method that would be responsible for creating the initial A instance (at the same module as Foo) and then reusing that instance in a refresh method.
class Foo:
def __init__(self, a, b):
self.a = a
self.b = b
#classmethod
def start(cls):
a = A()
b = B(a.var)
return cls(a, b)
def refresh(self):
b = B(self.a.var)
return self.__class__(self.a, b)
Then, your main function would look something like:
def main():
f = Foo.start()
while f.run():
f = f.refresh()
By overwriting the f variable, you are effectively deleting the reference to the old instance which will eventually be garbage collected.
i'm newer in python but i have some package from other languages . Here's my question :
i need to change an instance reference inside a function.This instance is passed as parameter.
but i didn't know how to do it. I think i miss something in Python basics.The code bellow is given as example for what i want:
class Foo(object):
def __init__(self,a):
self.a = a
def func(a):
b = Foo(3)
a = b
var1 = Foo(5)
print(var1.a) # 5
func(var1)
print(var1.a) # it display 5 not 3
You can make func return a and then assign that to var1 as follows:
def func(a):
b = Foo(3)
a = b
return a
var1 = Foo(5)
print(var1.a) # 5
var1 = func(var1)
print(var1.a) # 3
>>> var1.a
3
What you were doing in your code is that you were changing the pointer for the local variable a in your func(a) method. However, if you want to change the var1 pointer, you have to assign the changed a variable that you passed as an argument.
One way is to use an umutable object such as the list and the property functions that automagically does what you need.
class Foo(object):
def __init__(self, value):
self._a = [value]
def __geta(self):
return self._a[0]
def __seta(self, obj):
self._a.insert(0, obj)
self._a.pop(1)
a = property(__geta, __seta)
var1 = Foo(5)
print var1.a
var1.a = 3
print(var1.a)
I want to use the variables i have declared inside a function in one class, in another class.
For example i want to use the variable "j" in another class. Is it possible? (I read somewhere that it might have something to do with instance variables but fully couldn't understand the concept).
class check1:
def helloworld(self):
j = 5
class check1:
def helloworld(self):
self.j = 5
check_instance=check1()
print (hasattr(check_instance,'j')) #False -- j hasn't been set on check_instance yet
check_instance.helloworld() #add j attribute to check_instance
print(check_instance.j) #prints 5
but you don't need a method to assign a new attribute to a class instance...
check_instance.k=6 #this works just fine.
Now you can use check_instance.j (or check_instance.k) just like you would use any other variable.
This may seems a little bit like magic until you learn that:
check_instance.helloworld()
is completely equivalent to:
check1.helloworld(check_instance)
(If you think about it a little bit, that explains what the self parameter is).
I'm not completely sure what you're trying to achieve here -- There are also class variables which are shared by all instances of the class...
class Foo(object):
#define foolist at the class level
#(not at the instance level as self.foolist would be defined in a method)
foolist=[]
A=Foo()
B=Foo()
A.foolist.append("bar")
print (B.foolist) # ["bar"]
print (A.foolist is B.foolist) #True -- A and B are sharing the same foolist variable.
j cannot be seen by another class; however, I think you meant self.j, which can.
class A(object):
def __init__(self, x):
self.x = x
class B(object):
def __init__(self):
self.sum = 0
def addA(self, a):
self.sum += a.x
a = A(4)
b = B()
b.addA(a) # b.sum = 4
Using class inheritane it is very easy to "share" instance variables
example:
class A:
def __init__(self):
self.a = 10
def retb(self):
return self.b
class B(A):
def __init__(self):
A.__init__(self)
self.b = self.a
o = B()
print o.a
print o.b
print o.retb()