I am new to python and i am not sure how this is working. Code is as below:
class test():
d=0
def __init__(self):
self.d=self.d+1;
D=test()
print D.d
D1=test()
print D1.d
D2=test()
print D2.d
Output is
1,1,1 # This should not be
Now using this :
class test():
d=[]
def __init__(self):
self.d.apend("1");
D=test()
print D.d
D1=test()
print D1.d
D2=test()
print D2.d
Result is (This should be)
['1']
['1', '1']
['1', '1', '1']
So i am not sure why integer value is not being treated as class variable while list is being treated.
In the first example,
self.d = self.d + 1
rebinds self.d, making it independent of test.d.
In the second example,
self.d.append("1")
modifies test.d.
To see that for yourself, print id(self.d) at the end of both constructors.
If you modified the second example to match the first:
self.d = self.d + ["1"]
you'd see that the behaviour would also change to match.
If you want to modify a class variable, do:
class test(object):
d=0
def __init__(self):
type(self).d=self.d+1;
D=test()
print D.d
D1=test()
print D1.d
D2=test()
print D2.d
You don't need the type on the right hand side of the assignment, because this way you never create an instance variable d. Note that new-style classes are necessary to this.
type is a function (actually a callable - it is also a class; but don't worry about that for now) which returns the class of its argument. So, type(self) returns the class of self. Classes are first class objects in Python.
Demo here: http://ideone.com/JdNpiV
Update: An alternative would be to use a classmethod.
To address a class variable use class_name.variable_name, giving :
class test(object):
d=0
def __init__(self):
test.d = test.d + 1;
NPE's answer tells you what is going wrong with your code. However, I'm not sure that it really tells you how to solve the issue properly.
Here's what I think you want, if each test instance should have a different d value in an instance variable:
class test(object): # new style class, since we inherit from "object"
_d = 0 # this is a class variable, which I've named _d to avoid confusion
def __init__(self):
self.d = test._d # assign current value of class variable to an instance variable
test._d += 1 # increment the class variable
Now, you can create multiple instances and each one will get a unique value for d:
>>> D0 = test()
>>> D1 = test()
>>> D2 = test()
>>> print D0.d
0
>>> print D1.d
1
>>> print D2.d
2
Related
I'm studying for a python course and one of the exercise was to create a decorator for this class that returns every int variables.`
#decoratoreDiClasse
class MyClass:
def __init__(self):
self.a = 1
self.b = 2
self.c = 'w'`
My problem is that the list is always empty beacuse dict does not return the variables inside init,how can i solve my problem?
i've written my decorator below
def decoratoreDiClasse(cls):
def elencaVariabili():
lista = []
print(cls)
lista1 = cls.__dict__
print(lista1)
for ab in lista1:
if isinstance(ab, int):
lista.append(ab)
return lista
setattr(cls, "elencaVariabili", elencaVariabili())
return cls
here's the part of the main that should print the variables,I cannot change anything apart from "decoratoreDiClasse" due to the teacher request.
for v in x.elencaVariabili():
print(v, end=' ')
It looks like you're supposed to have your decorator add a method to the class that prints out integer-valued attributes on an instance it's called on. That's not what you're currently trying to do, as your code tries to find the variables on the class instead of on an instance later on.
Think of what you're doing as a method, and it will be a lot simpler:
def decoratoreDiClasse(cls):
def elencaVariabili(self): # this is a method, so it should take self!
lista = [value for value in self.__dict__.values() # loop over our attribute values
if isinstance(value, int)] # and pick out the integers!
return lista
setattr(cls, "elencaVariabili", elencaVariabili) # don't call the method here
return cls
It's not entirely clear from your code if you're supposed to be returning the names of the integer variables or just the values themselves. I went with just the values, but if you need the variable names, you may need to change the list comprehension to iterate over the items() of the instance's dictionary rather than just the values().
This question already has answers here:
How can I choose a custom string representation for a class itself (not instances of the class)?
(7 answers)
Closed 3 years ago.
Suppose you have a class in python. We'll call it C. And suppose you create an instance of it somewhere in your script, or in interactive mode: c=C()
Is is possible to have a "default" method in the class, such that when you reference the instance, that default method gets called?
class C(object):
def __init__(self,x,y):
self.x=x
self.y=y
def method0(self):
return 0
def method1(self):
return 1
def ...
...
def default(self):
return "Nothing to see here, move along"
And so on.
Now I create an instance of the class in interactive mode, and reference it:
>>> c=C(3,4)
>>> c
<__main__.C object at 0x6ffffe67a50>
>>> print(c)
<__main__.C object at 0x6ffffe67a50>
>>>
Is is possible to have a default method that gets called if you reference the object by itself, as shown below?
>>> c
'Nothing to see here, move along'
>>> print(c)
Nothing to see here, move along
>>>
What you're looking for is the __repr__ method, which returns the string representation of an instance of the class. You can override the method like this:
class C:
def __repr__(self):
return 'Nothing to see here, move along'
so that:
>>> c=C()
>>> c
Nothing to see here, move along
>>> print(c)
Nothing to see here, move along
>>>
Any code that you want to run when an object starts should go in __init__() and if you want to alter the effect of print(instance) you can overwrite the __repr__() of the object. Together it would look like:
class C(object):
def __init__(self, x, y):
self.x = x
self.y = y
print(self.__repr__())
def __repr__(self):
return 'nothing to see here'
c = C(3, 4)
print(c)
Outputting:
nothing to see here
nothing to see here
Where the first is printed when the class is made by calling print(self.__repr__()) and the next print comes from print(c)
is there any difference between these two method?
option1 :
class a(object):
def __init__(self):
self.x = 123
self.y = 345
option2 :
class a(object):
x = 123
y = 345
is there any difference between these two options?
Thanks in advance.
An example of the first method (instance level variables):
instance0 = a()
instance1 = b()
instance0.x = 5
print instance1.x # prints 123
print a.x # undefined variable - x is not defined
An example of the second method (class level variables):
instance0 = a()
instance1 = b()
instance0.x = 5
print instance1.x # prints 5
print a.x # prints 5
The second method, the variables are assigned at the class level meaning changing this value propagates to all instances of that class. You can also access the variables without an instance of the class.
Yes, in the first case each object of class a has its own copy of x and y, in the second case all objects of class a share them.
By the way, if your starting out with Python, use a capital for the first character of your class names, e.g. MyClass. People are used to that and it will help you understand your own programs once they get bigger.
In Python I have a for loop which calls a class, which in turn calls another class and so on, with classes manipulating data, performing sql inserts etc. The final class contains a list of all the files which have been created. I want to access this list from outside the class but I cannot work out how to!
(I know there is also a loop issue-will explain more below!)
A basic example is:
#A class to create the list
class Create_list():
def list(self,j):
l=j+1
#pass this variable to another class, get_list
Get_list().input(l)
#class get_list receives the number from create_list and appends it to mylist
class Get_list():
def input(self,l):
mylist=[]
mylist.append(l)
#print mylist
# loop through a list of numbers and feed them into the create_list class
j=10
for k in range(j):
Create_list().list(k)
#I want to access the list here. I have tried all of the below
readlist=Get_list().input().mylist # with ()
readlist=Get_list.input.mylist # without ()
x=Create_list() # create an object with class name
mylist=x.list().mylist #use above object
I have tried all the approaches in the last block of code.
I can't use the first two as the function list requires an input, which comes from the preceding class. (the error says that list() requires two arguments, only one is provided (self I assume)).
I have tried assigning the class to an object but this too does not work.
I realise that the for loop means that if I were to print mylist within def input there is only the value from that value of j.
I basically would like to access mylist, which has a list of values (l) from all of the values in j after that for loop has run.
Lots of stuff is wrong here so I'll just show a simple way to do it:
class Create_list(object):
def __init__(self):
self.list = []
def input_list(self, x):
l = x + 1
self.list.append(l)
j=10
cl = Create_list()
for k in xrange(j):
cl.input_list(k)
print cl.list
Another possibility is to return the list:
def add_one_to(j):
l=j+1
return(l)
def store(mylist, l):
mylist.append(l)
return(mylist)
Usage:
>>> mylist = []
>>> myintegerplusone = add_one_to(1)
>>> store(mylist, myintegerplusone)
>>> print(mylist)
[2]
In that case you could imagine a function as a craftsman, you give him something to fix/manipulate and he then returns the fixed/manipulated good back to you.
I think what you want is to store inside the class object the list using the "self" method and then access it from outside.
Try this code:
class CreateList():
def __init__(self):
self.list = []
if __name__ == "__main__":
c = CreateList()
c.list.append(4)
print c.list
Apologies if someone has already addressed this, but I couldn't find an answer.
I have a problem where I overrode __cmp__ for a custom class, similar to this:
class MyClass(object):
def __init__(self, prop):
self.prop = prop
def __cmp__(self, other):
return cmp(self.prop, other.prop)
a = MyClass(1)
b = MyClass(2)
c = MyClass(3)
d = MyClass(1)
my_list = [a, b, c]
print a in my_list
print b in my_list
print c in my_list
print d in my_list
# Output:
#
# True
# True
# True
# True
Reading the docs tells me that this is expected, because:
For the list and tuple types, x in y is true if and only if there exists an index i such that x == y[i] is true.
My question is two-fold:
Why does Python (2.7) use == rather than is to test list membership?
Is there a better way to be doing this, such that I can test whether a specific instance of my class is actually in a container and be able to compare instances based on their attributes?
Why does Python (2.7) use == rather than is to test list membership?
Because equality is usually more interesting than identity for containment checking, especially when two different objects can have the same value.
>>> ('Hello, ' + 'world!') is 'Hello, world!'
False
>>> ('Hello, ' + 'world!') == 'Hello, world!'
True
Is there a better way to be doing this, such that I can test whether a specific instance of my class is actually in a container and be able to compare instances based on their attributes?
Not especially.
The list contains a value equal to the variable, not a reference to the variable. Think about it this way. Are these two code samples the same? What makes them different?
class Person:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
# sample one
sam = Person('Sam')
bob = Person('Bob')
people = [sam, bob]
The first sample is when you should use the is keyword. You're trying to test if the object in the list is the object outside of the list, meaning the sam inside the list is stored in the same place in memory as the sam outside the list.
# sample two
sam = Person('Sam')
bob = Person('Bob')
people = [Person('Sam'), Person('Bob')]
This sample is when you should use the double equals keyword. You're trying to test if the object in the list has the value when compared to the object outside of the list. Notice, that because we instantiated to different people with the name Sam, they will be equal in value but not the same object.