I'm coming from a C++ background to python
I have been declaring member variables and setting them in a C++esqe way like so:
class MyClass:
my_member = []
def __init__(self,arg_my_member):
self.my_member = arg_my_member
Then I开发者_Go百科 noticed in some open source code, that the initial declaration my_member = []
was completely left out and only created in the constructor.
Which obviously is possible as python is dynamic.
My question is, is this the preferred or Pythonic way of doing things, and are there and pros and cons of either?
The way you are doing it means that you'll now have a "static" member and a "non-static" member of the same name.
class MyClass:
my_member = []
def __init__(self, arg_my_member):
self.my_member = arg_my_member
>>> a = MyClass(42)
>>> print a.my_member
42
>>> print MyClass.my_member
[]
If you define it inside the class then it is a class variable and if you define it inside the constructor it is an object variable. So if you don't define it inside the constructor ALL instances of the class share the same class variable.
Both ways are acceptable for python, except in case of mutable values. When you declare it like in your example, you can get very unexpected result:
>>> class MyClass:
... my_member = []
...
>>> A = MyClass()
>>> B = MyClass()
>>> A.my_member.append(1)
>>> A.my_member
[1]
>>> B.my_member.append(2)
>>> B.my_member
[1, 2]
>>> A.my_member
[1, 2]
>>> MyClass.my_member
[1, 2]
Since class members are generated only once, when class itself is being processed at module load. If your member is intended to be used in instance scope, you should set it in __init__
Immutable values are fine tho.
This creates a class attribute called my_member
class MyClass:
my_member = []
If the instances did not have an instance variable called my_member, all the instances would have access to the same list via self.my_member
.
Since you are creating an instance variable called my_member
it is quite likely that the class variable is never used and is just a sign of confusion
精彩评论