views:

70

answers:

5

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 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?

+3  A: 

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.

TheCandyMan666
A: 

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

gnibbler
A: 

These are two different things. my_member is a class variable (like a static class member in C++ and friends) because it is created at class level. You can access it as instance.my_member, but it's shared across all instances (and you are therefore better off referencing it as cls.my_member). Setting them in __init__ as self.my_member creates a "real" member (an instance variable) for every the instance.

delnan
+6  A: 

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
[]
UncleBens
A: 

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.

Daniel Kluev