2

I have a class Foo which contains a datamember of type Bar. I can't make a generalized, "default" Bar.__init__() - the Bar object is passed into the Foo.__init__() method.

How do I tell Python that I want a datamember of this type?


class Foo:

# These are the other things I've tried, with their errors    
    myBar         # NameError: name 'myBar' is not defined
    Bar myBar     # Java style: this is invalid Python syntax.
    myBar = None  #Assign "None", assign the real value in __init__. Doesn't work 
#####

    myBar = Bar(0,0,0) # Pass in "default" values. 
    def __init__(self, theBar):
        self.myBar = theBar

    def getBar(self):
        return self.myBar

This works, when I pass in the "default" values as shown. However, when I call getBar, I do not get back the one I passed in in the Foo.__init__() function - I get the "default" values.


b = Bar(1,2,3)
f = Foo(b)
print f.getBar().a, f.getBar().b, f.getBar().c

This spits out 0 0 0, not 1 2 3, like I'm expecting.

If I don't bother declaring the myBar variable, I get errors in the getBar(self): method (Foo instance has no attribute 'myBar').

What's the correct way to use a custom datamember in my object?

1
  • 2
    Sounds like the issue is with your Bar class rather than Foo. What is that class? Commented Aug 10, 2012 at 14:41

4 Answers 4

7

You don't need to tell Python you are going to add a certain data member – just add it. Python is more dynamic than e.g. Java in this regard.

If bar instances are essentially immutable (meaning they are not changed in practice), you can give the default instance as default value of the __init__() parameter:

class Foo:
    def __init__(self, the_bar=Bar(0,0,0)):
        self.my_bar = the_bar

All Foo instances uisng the default value will share a single Bar instance. If the Bar instance might be changed, this is probably not what you want, and you should use this idiom in this case:

class Foo:
    def __init__(self, the_bar=None):
        if the_bar is None:
            the_bar = Bar(0,0,0)
        self.my_bar = the_bar

Note that you shouldn't usually write getters and setters in Python. They are just unnecessary boilerplate code slowing down your application. Since Python supports properties, you also don't need them to be future-proof.

Sign up to request clarification or add additional context in comments.

2 Comments

I didn't know about the non-use of getters/setters in Python - thanks for that.
@simont: See dirtsimple.org/2004/12/python-is-not-java.html for more on Javaisms in Python.
2

The correct way is to do nothing other than assign it in the constructor.

class Foo: 
    def __init__(self, bar):                                                      
        self.bar = bar

    def getbar(self):
        return self.bar

1 Comment

and the even more correct way is not to have a getbar() method at all.
2

You definitely don't have to declare bar ahead of time.

It sounds like you want Foo.bar to default to a value if one isn't specified so you might do something like this:

class Foo:
    def __init__(self, bar=None):
        # one of many ways to construct a new
        # default Bar if one isn't provided:
        self._bar = bar if bar else Bar(...)

    @property
    def bar(self):
        """
        This isn't necessary but you can provide proper getters and setters
        if you prefer.

        """
        return self._bar

    @bar.setter
    def bar(self, newbar):
        """
        Example of defining a setter
        """
        return self._bar = newbar

Typically just naming the variable appropriately and omitting the setter is considered more more 'pythonic'.

class Foo:
    def __init__(self, bar=None):
        self.bar = bar if bar else Bar(...)

Comments

1

You don't declare variables in Python, and variables are untyped.

Just do:

class Foo(object): 
    def __init__(self, bar):                                                      
        self.bar = bar

    def getbar(self):
        return self.bar

I suspect that the issue is caused by you using old-style classes, which are kind of odd. If you inherit from object, you get a new-style class, which is designed to be much less surprising.

2 Comments

What do you mean by 'new-style' vs 'old-style' classes (and would you mind adding a link to some documentation for them)?
@simont Python hastwo types of classes, old-style and new-style. New-style classes were added after it became clear that the half-baked hack that is old-style was causing everyone problems. From your request for docs, I take it that you have yet to find the language reference: docs.python.org/reference/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.