tags:

views:

72

answers:

4

Hello I need an uninstantiated class attribute and I am doing this:

>>> class X:
...     def __init__(self, y=None):
...             self.y = list()

Is this ok? If no, is there another way of doing it. I can't instantiate this attribute in __init__ cause I would be appending to this later.

+2  A: 

If you need a initial empty attribute, to which you will later add items, just do this

class X(object):
    def __init__(self):
        self.y = []

Few things to note here (differences from your version)

  • Derive class from object
  • y = list() is same as y = [] and is preferred.
  • No need of having default argument y=None, when you are not using it
Anurag Uniyal
But doesn't explicitly specifying: `def __init__(self, y)` make it better?
sukhbir
@PulpFiction: No. Unless the constructor actually uses an argument, the argument shouldn't be there.
David Zaslavsky
@David: So using y=None is a bad practice?
sukhbir
@PulpFiction: if the constructor doesn't actually use the value of `y`, then yeah, I'd say it is bad practice.
David Zaslavsky
+4  A: 

Define the y var on the class-level attribute. You will need to initialize it to something, even it's an empty list (as you were doing before).

>>> class X:
...     y = [] 
...     def __init__(self):
...         pass

Update based on your comments:

You mentioned that you were mixed on the terminology (I'm assuming between class and instance variables), so here's what'll happen if you use this class (and is probably not what you want).

>>> class X:
...     y = [] # Class level attribute
...     def __init__(self):
...             pass
... 
>>> x = X()
>>> x.y.append(1)
>>> x.y
[1]
>>> x.y.append(2)
>>> z = X()
>>> z.y.append(3)
>>> z.y
[1, 2, 3]
>>> X.y.append(4)
>>> [1, 2, 3, 4]

Notice that when you add a variable to the class it sticks around between constructions. In the previous code we instantiated the variable x and the variable z as an instance of X. While we added to the y variable in the z instance, we still appended to the class variable y. Note on the very last line (X.y.append(4)) I append an item using a reference to the class X.

What you probably want is based off of your original post:

>>> class X:
...     def __init__(self, y=None):
...             self.y = y or list() # Instance level attribute.  Default to empty list if y is not passed in.
... 
>>> x = X()
>>> x.y.append(1)
>>> x.y
[1]
>>> z = X()
>>> z.y.append(2)
>>> z.y
[2]
>>> 
>>> s = X()
>>> s.y
[]
>>> t = X(y=[10])
>>> t.y
[10]

Notice how a new list is created with each instance. When we create a new instance z and try to append to the y variable we only get the value that was appended, rather than keeping all of the existing additions to the list. In the last instantiation (t) example the constructor passes in the y parameter in it's construction, and thus has the list [10] as it's y instance variable.

Hopefully that helps. Feel free to ask any more uncertainties as comments. Also, I would suggest reading up on the Python class documentation here.

sdolan
What is wrong with my method of doing it? :)
sukhbir
You said "class attribute", so that's what I did. If you want to stick with your original instance based way I would change the code to `self.y = y or list()`, so if so if someone passes does pass in `y` then it is used, otherwise you create an empty list.
sdolan
Thanks and sorry for messing up the terminology.
sukhbir
@sdolan: Thank you for all the help.
sukhbir
@sdolan: I understand it now.
sukhbir
@PulpFiction: Not a problem. I've updated the post with a bit more detail based on your comments and a link to the Python class documentation that I recommend you read through.
sdolan
+2  A: 

to add to the others statements: there are class variables and instance variables, they are separate and cannot be accessed the same way. ex:

class foo:
    x=[]
    def __init__(self):
        self.y=[]

foo.x.append(20)
f = foo()
f.y.append(30)
print f.y
print foo.x
print f.x
print foo.y
#results-------------------------------
[30]
[20]
[20]
Traceback (most recent call last):
  File "C:\Users\adminuser\Desktop\temp.py", line 12, in <module>
    print foo.y
AttributeError: class foo has no attribute 'y'
ebt
So what is `x=[]` - class variable? Sorry but trying to understand the terminology here.
sukhbir
@PulpFiction: yes, x is a class attribute and is shared between all instances of the class. You can also access it without creating an instance. y is an object attribute and a new one is created for each instance of the class.
Dave Kirby
A: 

Let me extent the answer of Anurag Uniyal a little bit

class X(object):
    def __init__(self, y=None):
        if y is None:
            # y wasn't specified, create an empty list
            self.y = []
        else:
            # y was specified, use it
            try:
                self.y = list(y) #create y's copy so that the original
                              # variable is safe
            except TypeError:
                # ooops, couldn't create a list. We might warn
                # the user or something. Oh, nevermind
                self.y = []
bgbg