I am relatively new to Python and I am using Python 2.7.x
I have a question regarding namespaces in Python:
class Team():
x = 2
def p(self):
print x
a = Team()
a.p()
When I run the code, it says global x is not defined. Shouldn't x belong to the Team object? My goal is to create a Team class where x has a default value of 2.
In Java it would be something like:
class Team()
{
int x = 2;
}
a = new Team();
If you want an instance attribute and a default value of 2 :
class Team(object): # use object for new style classes
def __init__(self, x=2):
self.x = x # use self to refer to the instance
def p(self):
print self.x # self.x
a = Team()
a.p()
2
b = Team(4) # give b a different value for x
b.p()
4
Difference between class vs instance attributes
new vs old style classes
If you want make x as class variable, just try this way:
class Team(object):
x = 2
def __init__(self):
pass
print Team.x
Team.x = 3
print Team.x
You don't need to instance to get the value and you can change it as you want.
If you want to make the num as instance property, you have to use self(like this in Java):
class Team(object):
def __init__(self, num):
self.num = num
def get_num(self):
return self.num
def set_num(self, change_num):
self.num = change_num
t1 = Team(2)
print t1.get_num()
t1.set_num(3)
print t1.get_num()
Related
I want to create a global variable inside a class method and then change it by other functions. This is my code:
def funcA():
global x
print(x)
x = 2
a = funcB()
return x
def funcB():
global x
print(x)
x = 4
return 2
class A():
def method():
x = 0
return funcA()
A.method()
So I create variable x inside class method and then in all other methods which uses this variable I wrote global x. Unfortunately it doesn't work. What should I change? funcA should print 0, funcB should print 2 and the final results should be 4.
In general, use of global variables is frowned upon. If you see that a group of methods all need to manipulate the same variable it is often a sign that you actually want a class. You are on the right track trying to define the class, but unfortunately the syntax is a little more complicated
Here is one suggestion:
class A:
def method(self):
self.x = 0 # note use of self, to refer to the class instance
return self.funcA()
def funcA(self):
print(self.x)
self.x = 2
self.funcB()
def funcB(self):
print(self.x)
self.x = 4
a = A() # making an instance of A
a.method() # calling the method on the instance
print(a.x) # showing that x has become 4
create the variable globally. just add x = 0 at the starting of your code, it will work
x = 0
def funcA():
global x
print(x)
x = 2
a = funcB()
return x
def funcB():
global x
print(x)
x = 4
return 2
class A():
def method():
return funcA()
print(A.method())
It should work now, the problem was that you declared x inside class A, so it wasn't global.
I found a bug in my program and I did some digging before making something much simpler to understand the problem.
In a nutshell: I'm creating two objects from a class where I want to store an object from another class. But When I'm doing this, both objects are getting the same result. How can I prevent this duplication?
It seems like both objects are pointing on the same class.
# Sub-class that may not be extendable
class MyClass:
def __init__(self, number):
self.number = number
#classmethod
def add_number(cls, number=0):
return cls(number)
# Main class
class MyOtherClass:
my_objects = []
"""
Initialize the class
:param List[MyClass] my_objects: List of MyClass objects
"""
def __init__(self, this_object):
self.my_objects.append(this_object)
if __name__ == "__main__":
my_object1 = MyOtherClass(MyClass.add_number())
my_object2 = MyOtherClass(MyClass.add_number())
for i in range(100):
my_object1.my_objects.append(MyClass.add_number(i))
print(f"Appending obj1 : {my_object1.my_objects[i].number}")
for y in range(100, 0, -1):
my_object2.my_objects.append(MyClass.add_number(y))
print(f"Appending obj2 : {my_object2.my_objects[y].number}")
# later
z = 0
while z < len(my_object1.my_objects):
print(f"obj1 : {my_object1.my_objects[z].number}")
print(f"obj2 : {my_object2.my_objects[z].number}")
z += 1
class CLASS:
var_total = 0
def __init__(self, var):
self.var = var
CLASS.var_total+=var
obj_one = CLASS(48)
obj_two = CLASS(74)
obj_three = CLASS(12)
I don't want the var_total to be static, how do you code it to update automatically as the var property of the objects changes later in the code?
Rather than create different instances with init, why not create one and use the method.
class MyClass:
total= 0
def add_prop(self,var):
self.total += var
obj = MyClass()
obj.add_prop(48
obj.add_prop(78)
obj.add_prop(12)
obj.total #124
or if you need to grab the value later in your code
class myclass:
total= 0
var = 0
def var_data(self,var):
self.var= var
self.totaladd(var)
def totaladd(self,value):
self.total += value
I have a program where an object creates another object. However, the second object that gets created needs to be able to access the first. Is this possible?
EG (pseudocode)
class parentObject():
parentVar = 1
# Create Child
x = childObject()
class childObject():
#Assign Var to the Var of the childs parent
childVar = parent.parentVar
>>> x.childVar = 1
is there a straitforward way to do this?
UPDATE:
I don't want to inheret the class, I need to be able to access the actual object that created it, as each object created from that class has different values.
Why not inherit the class?
class parentObject():
parentVar = 1
class childObject(parentObject):
childVar = parentObject.parentVar
>>> x = childObject()
>>> print(x.childVar)
1
If you are going to have different instances of the class, you should do it as this instead:
class parentObject(object):
def __init__(self):
self.parentVar = 1
class childObject(parentObject):
def __init__(self):
super(childObject, self).__init__()
self.childVar = self.parentVar
>>> x = childObject()
>>> print(x.childVar)
1
If you want a reference to the "parent" class, but inheritance is illogical, consider sending self in to the constructor:
class Room:
def __init__(self, name):
self.name = name
self.furniture = []
def add_chair(self):
self.furniture.append(Chair(self))
def __str__(self):
return '{} with {}'.format(self.name, self.furniture)
class Chair:
def __init__(self, room):
self.room = room
def __str__(self):
return 'Chair in {}'.format(self.room.name)
r = Room('Kitchen')
r.add_chair()
r.add_chair()
print r
print r.furniture[0]
Output:
Kitchen with [<__main__.Chair instance at 0x01F45F58>, <__main__.Chair instance at 0x01F45F80>]
Chair in Kitchen
How do these 2 classes differ?
class A():
x=3
class B():
def __init__(self):
self.x=3
Is there any significant difference?
A.x is a class variable.
B's self.x is an instance variable.
i.e. A's x is shared between instances.
It would be easier to demonstrate the difference with something that can be modified like a list:
#!/usr/bin/env python
class A:
x = []
def add(self):
self.x.append(1)
class B:
def __init__(self):
self.x = []
def add(self):
self.x.append(1)
x = A()
y = A()
x.add()
y.add()
print("A's x:", x.x)
x = B()
y = B()
x.add()
y.add()
print("B's x:", x.x)
Output
A's x: [1, 1]
B's x: [1]
Just as a side note: self is actually just a randomly chosen word, that everyone uses, but you could also use this, foo, or myself or anything else you want, it's just the first parameter of every non static method for a class. This means that the word self is not a language construct but just a name:
>>> class A:
... def __init__(s):
... s.bla = 2
...
>>>
>>> a = A()
>>> a.bla
2
A.x is a class variable, and will be shared across all instances of A, unless specifically overridden within an instance.
B.x is an instance variable, and each instance of B has its own version of it.
I hope the following Python example can clarify:
>>> class Foo():
... i = 3
... def bar(self):
... print 'Foo.i is', Foo.i
... print 'self.i is', self.i
...
>>> f = Foo() # Create an instance of the Foo class
>>> f.bar()
Foo.i is 3
self.i is 3
>>> Foo.i = 5 # Change the global value of Foo.i over all instances
>>> f.bar()
Foo.i is 5
self.i is 5
>>> f.i = 3 # Override this instance's definition of i
>>> f.bar()
Foo.i is 5
self.i is 3
I used to explain it with this example
# By TMOTTM
class Machine:
# Class Variable counts how many machines have been created.
# The value is the same for all objects of this class.
counter = 0
def __init__(self):
# Notice: no 'self'.
Machine.counter += 1
# Instance variable.
# Different for every object of the class.
self.id = Machine.counter
if __name__ == '__main__':
machine1 = Machine()
machine2 = Machine()
machine3 = Machine()
#The value is different for all objects.
print 'machine1.id', machine1.id
print 'machine2.id', machine2.id
print 'machine3.id', machine3.id
#The value is the same for all objects.
print 'machine1.counter', machine1.counter
print 'machine2.counter', machine2.counter
print 'machine3.counter', machine3.counter
The output then will by
machine1.id 1
machine2.id 2
machine3.id 3
machine1.counter 3
machine2.counter 3
machine3.counter 3
I've just started learning Python and this confused me as well for some time. Trying to figure out how it all works in general I came up with this very simple piece of code:
# Create a class with a variable inside and an instance of that class
class One:
color = 'green'
obj2 = One()
# Here we create a global variable(outside a class suite).
color = 'blue'
# Create a second class and a local variable inside this class.
class Two:
color = "red"
# Define 3 methods. The only difference between them is the "color" part.
def out(self):
print(self.color + '!')
def out2(self):
print(color + '!')
def out3(self):
print(obj2.color + '!')
# Create an object of the class One
obj = Two()
When we call out() we get:
>>> obj.out()
red!
When we call out2():
>>> obj.out2()
blue!
When we call out3():
>>> obj.out3()
green!
So, in the first method self specifies that Python should use the variable(attribute), that "belongs" to the class object we created, not a global one(outside the class). So it uses color = "red". In the method Python implicitly substitutes self for the name of an object we created(obj). self.color means "I am getting color="red" from the obj"
In the second method there is no self to specify the object where the color should be taken from, so it gets the global one color = 'blue'.
In the third method instead of self we used obj2 - a name of another object to get color from. It gets color = 'green'.