Defining attributes of a class in Python [duplicate] - python

This question already has answers here:
How should I choose between using instance vs. class attributes?
(4 answers)
Closed 8 years ago.
How should I define the attributes of a class?
class Example:
def __init__(self,n,m):
self.n=n
self.m=m
or in this way:
class Example:
m=0
n=0
def __init__(self,n,m):
self.n=n
self.m=m
If I define an attribute outside the constructor, is it a static variable?

I think you are confusing instance variables and variables of the class itself (you could call them static if you are coming from java). Have a look at this demo (note that __init__ needs two underscores).
class Example:
m=0
n=0
def __init__(self,n,m):
self.n=n
self.m=m
e = Example(1,2)
print(e.m) # 2
print(e.n) # 1
print(Example.m) # 0
print(Example.n) # 0
In your second code, Example has the class variables m and n, and each instance of an Example object will have instance members self.m and self.n.

This way:
class Example:
def __init__(self,n,m):
self.n=n
self.m=m
Double score the init, like this: __init__, not like this _init_!
m=0 and n=0 are class attributes, and don't have anything with self.n and self.m, which are instance variables.

Related

Python 3.5 handling lists strangely [duplicate]

This question already has answers here:
python class instance variables and class variables
(4 answers)
Closed 5 years ago.
I came across some rather strange behavior.
class Example:
test = []
def __init__(self):
print(self.test)
self.test.append(0)
ex1 = Example()
ex2 = Example()
ex3 = Example()
I'd expect this to output [] every time, however, I get:
[]
[0]
[0, 0]
What is this wizardry? Could you help me understand?
Thank, you!
Edit:
Hey, thank you for the quick answers.
Just to clarify, if "test" is static then why do I not notice this behavior when I replace "self.test.append(0)" with "self.test = [0]"?
test is a static class attribute, which you are continually updating with values. Python is different from some other languages in this way. To make it an object attribute, use self.test = [] in your constructor.
test there is a class-level static variable, which is shared between the instances of the class.
You'll want to initialize test within the __init__ method.
class Example:
def __init__(self):
self.test = []
print(self.test)
self.test.append(0)

Python, set class variable to int value not int type [duplicate]

This question already has answers here:
Should I, and how to, add methods to int in python?
(1 answer)
Can I add custom methods/attributes to built-in Python types?
(8 answers)
Closed 5 years ago.
If I have a class such as this
class foo():
def __init__(self, value = 0):
self.__value = value
def __set__(self, instance, value):
self.__value = value
def calc(self):
return self.__value * 3
def __repr__(self):
return str(self.__value)
I can now make a variable of the class foo and use it's functions.
n = foo(3)
print(n.calc())
No problems there but if I keep going with something like this.
n = 5
print(n.calc())
I will get an error, because I have now set n to an int object with the value 5 and thus does not have the calc() function.
I normally work with C++ so I'm confused because I thought that the __set__ function was supposed to override the = operator and then set __value to the value of 5 just like if I were to to use
operator=(int value)
In C++, I have looked for an explanation but have not found any.
All help appreciated.
As stated here.
The following methods only apply when an instance of the class
containing the method (a so-called descriptor class) appears in an
owner class (the descriptor must be in either the owner’s class
dictionary or in the class dictionary for one of its parents).

Self in python Class - I can do it with out it...? [duplicate]

This question already has answers here:
Why do you need explicitly have the "self" argument in a Python method? [duplicate]
(10 answers)
Closed 6 years ago.
Consider this code:
class example(object):
def __init__ (): # No self
test() # No self
def test(x,y): # No self
return x+y
def test1(x,y): # No self
return x-y
print(example.test(10,5))
print(example.test1(10,5))
15
5
This works as expected. I believe I can write a whole program not using self. What am I missing? What is this self; why is it needed in some practical way?
I have read a lot about it - (stack, Python documentation), but I just don't understand why it's needed, since I can obviously create a program without it.
You can perfectly create a program without it. But then you'd be missing one of the key features of classes. If you can do without self, I'd argue you can do without classes and just do something purely with functions :)
Classes allow you to create objects which have a PROPERTY associated to them, and self allows you to access those values. So say you have a square.
g code:
class Square(object):
def __init__ (self, length, height):
self.length = length # THIS square's length, not others
self.height = height # THIS square's height, not other
def print_length_and_height(self):
print(self.length, self.height) # THIS square's length and height
square1 = Square(2,2)
square2 = Square(4,4)
square1.print_length_and_height() # 2 2
square2.print_length_and_height() # 4 4
Now, this example is quite silly, of course, but i think it shows what SELF specifically is for: it refers to the particular instance of an object.
By all means, if you don't see the point to it, just do away with classes and just use functions, there nothing wrong with that.
You haven't utilised a class or object properly. Cutting out the garbage code, your program reduces to:
def test(x,y): #No class
return x+y
def test1(x,y): #No class
return x-y
print(example.test(10,5))
print(example.test1(10,5))
Output:
15
5
Your "class" is no more useful than if you wrapped your program in the nested structures:
if True:
for i in range(1):
...
A proper object will have attributes (data fields) and functions that operate on that data (see below). Your code has an empty object; hence, you have nothing on which to operate, no need for self, and no need for a class at all.
Rather, use a class when you need to encapsulate a data representation and associated operations. Below, I've reused some of your code to make example do some trivial complex number work. There are many extensions and improvements to make in this; I kept it relatively close to your original work.
class example(object):
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
sign = ' + ' if self.b >= 0 else ' - '
return str(self.a) + sign + str(abs(self.b)) + 'i'
def add(self, x):
self.a += x.a
self.b += x.b
def sub(self, x):
self.a -= x.a
self.b -= x.b
complex1 = example(10, 5)
complex2 = example(-3, 2)
complex1.add(complex2)
print(complex1)
complex2.sub(complex1)
print(complex2)
Output:
7 + 7i
-10 - 5i
Are you familiar with Object-Oriented Paradigm?
If you don't you should check it. Python is a Object-Oriented Language and self lets you define your object properties.
An example:
You have a class named Vehicle. A vehicle could be a bike, a car, even a plane. So something you can include is a name and a type.
class Vehicle():
def init(self, name, type): # Constructor
self.name = name
self.type = type
def info(self):
print("I'm a ")
print(self.name)
That's all, now you have a vehicle with name and type. Every instance of Vehicle would have a name and a type different or not and every intance can access its own variables. I'm sorry I can't explain it better. Firstable you need to know Object-Oriented Paradigm knowledge. Please comment my answer if you have doubts & I'll answer you or give a link where it comes explained better.

Python... Static variables? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Instance variables vs. class variables in Python
What is the difference between these two situations and how is it treated with in Python?
Ex1
class MyClass:
anArray = {}
Ex2
class MyClass:
__init__(self):
self.anArray = {}
It seems like the in the first example the array is being treated like a static variable. How does Python treat this and what is the reason for this?
In the first example, anArray (which in Python is called a dictionary, not an array) is a class attribute. It can be accessed using MyClass.anArray. It exists as soon as the class is defined.
In the second example, anArray is an instance attribute. It can be accessed using MyClass().anArray. (But note that doing that just throws away the MyClass instance created; a more sensible example is mc = MyClass(); mc.anArray['a'] = 5.) It doesn't exist until an instance of the class is created.
It is declared diffrent area.
Ex1 is Like global or static variable.
obj = MyClass()
obj2 = MyClass()
print "IS one instance ", id(obj.anArray) == id(obj2.anArray)
Ex2 is local attribute.
obj = MyClass()
obj2 = MyClass()
print "IS one instance ", id(obj.anArray) == id(obj2.anArray)

List in a Python class shares the same object over 2 different instances? [duplicate]

This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 15 days ago.
I created a class:
class A:
aList = []
now I have function that instantiate this class and add items into the aList.
note: there are 2 items
for item in items:
a = A();
a.aList.append(item);
I find that the first A and the second A object has the same number of items in their aList.
I would expect that the first A object will have the first item in its list and the second A object will have the second item in its aList.
Can anyone explain how this happens ?
PS:
I manage to solve this problem by moving the aList inside a constructor :
def __init__(self):
self.aList = [];
but I am still curious about this behavior
You have defined the list as a class attribute.
Class attributes are shared by all instances of your class.
When you define the list in __init__ as self.aList, then the list is an attribute of your instance (self) and then everything works as you expected.
You are confusing class and object variables.
If you want objects:
class A(object):
def __init__(self):
self.aList = []
in your example aList is a class variable, you can compare it with using the 'static' keyword in other languages. The class variable of course is shared over all instances.
This happened because list is a mutable object, and it is created once only when defining the class, that is why it becomes shared when you create two instances. Eg,
class A:
a = 0 #immutable
b = [0] #mutable
a = A()
a.a = 1
a.b[0] = 1
b = A()
print b.a #print 0
print b.b[0] #print 1, affected by object "a"
Therefore, to solve the problem, we can use constructor like what you have mentioned. When we put the list in constructor, whenever the object is instantiated, the new list will also be created.
In Python, variables declared inside the class definition, instead of inside a method, are class or static variables. You may be interested in taking a look at this answer to another question.

Categories

Resources