Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't set class attributes in python using a method

Initialising the Foo object does run the method func(), but the value of self.a gets set to None anyway.

How can I get the following code to work?

#!/usr/bin/env python

class Foo(object):

    def __init__(self, num):
        self.a = self.func(num)
        print self.a

    def func(self, num):
        self.a = range(num)
        print self.a

    def __str__(self):
        return str(self.a)


def main():
    f = Foo(20)
    print f

if __name__ == "__main__":
    main()

The output is:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
None
None
like image 339
shafty Avatar asked Jul 04 '12 20:07

shafty


People also ask

How do you set a method attribute in Python?

Python setattr() function is used to set a value to the object's attribute. It takes three arguments an object, a string, and an arbitrary value, and returns none. It is helpful when we want to add a new attribute to an object and set a value to it. The signature of the function is given below.

How do you set a class attribute in Python?

Use dot notation or setattr() function to set the value of class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime. Python stores class variables in the __dict__ attribute.

Can methods have attributes in Python?

Methods also gain getter syntax, and they currently access the attribute through the dictionary of the underlying function object. It is not possible to set attributes on bound or unbound methods, except by doing so explicitly on the underlying function object.

Are methods class attributes in Python?

A method is a function defined in the class. An attribute is an instance variable defined in the class. Here hello is a method, and name is an attribute. For Python 3, you don't need to inherit from object , and you need parentheses in the print call.


2 Answers

You're resetting self.a to the return value of the function. Since the function returns nothing, the value gets set to None.

def __init__(self, num):
    self.a = self.func(num)  # return value of function is None
    print self.a             # self.a is now None

def func(self, num):
    self.a = range(num)      # sets self.a to [0..19]
    print self.a             # prints [0..19]
    # implicit "return None"
like image 50
jterrace Avatar answered Sep 20 '22 06:09

jterrace


jterrace is correct. What's happening is that the func() method is printing first, not the init method. Consider this program:

#!/usr/bin/env python

class Foo(object):

    def __init__(self, num):
        self.a = self.func(num)
        print '__init__:', self.a

    def func(self, num):
        self.a = range(num)
        print 'func:', self.a

    def __str__(self):
        return str(self.a)

if __name__ == '__main__':
    f = Foo(20)
    print '__main__:', f

It's very similar to yours except I added __init__:, func:, and __main__: to the respective function's print statements. Run this and you should have a better understanding of what's going on.

like image 40
BrewerHimself Avatar answered Sep 20 '22 06:09

BrewerHimself