Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically setting class member variables in Python

Say, I have the following class in Python

class Foo(object):     a = None     b = None     c = None     def __init__(self, a = None, b = None, c = None):         self.a = a         self.b = b         self.c = c 

Is there any way to simplify this process? Whenever I add a new member to class Foo, I'm forced to modify the constructor.

like image 249
Jeeyoung Kim Avatar asked Oct 07 '10 18:10

Jeeyoung Kim


People also ask

Does Python automatically initialize variables?

For Python 3.7+ you can use a Data Class, which is a very pythonic and maintainable way to do what you want. It allows you to define fields for your class, which are your automatically initialized instance variables.

How do you assign a class variable 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.

How do you access member variables in Python?

The variables that are defined inside the methods can be accessed within that method only by simply using the variable name. Example – var_name. If you want to use that variable outside the method or class, you have to declared that variable as a global. def access_method( self ):

How do you initialize an instance variable in Python?

Create Instance Variables Instance variables are declared inside a method using the self keyword. We use a constructor to define and initialize the instance variables. Let's see the example to declare an instance variable in Python.


1 Answers

Please note that

class Foo(object):     a = None 

sets a key-value pair in Foo's dict:

Foo.__dict__['a']=None 

while

def __init__(self, a = None, b = None, c = None):     self.a = a 

sets a key-value pair in the Foo instance object's dict:

foo=Foo() foo.__dict__['a']=a 

So setting the class members at the top of your definition is not directly related to the setting of the instance attributes in the lower half of your definition (inside the __init__.

Also, it is good to be aware that __init__ is Python's initializer. __new__ is the class constructor.


If you are looking for a way to automatically add some instance attributes based on __init__'s arguments, you could use this:

import inspect import functools  def autoargs(*include,**kwargs):        def _autoargs(func):         attrs,varargs,varkw,defaults=inspect.getargspec(func)         def sieve(attr):             if kwargs and attr in kwargs['exclude']: return False             if not include or attr in include: return True             else: return False                     @functools.wraps(func)         def wrapper(self,*args,**kwargs):             # handle default values             for attr,val in zip(reversed(attrs),reversed(defaults)):                 if sieve(attr): setattr(self, attr, val)             # handle positional arguments             positional_attrs=attrs[1:]                         for attr,val in zip(positional_attrs,args):                 if sieve(attr): setattr(self, attr, val)             # handle varargs             if varargs:                 remaining_args=args[len(positional_attrs):]                 if sieve(varargs): setattr(self, varargs, remaining_args)                             # handle varkw             if kwargs:                 for attr,val in kwargs.iteritems():                     if sieve(attr): setattr(self,attr,val)                         return func(self,*args,**kwargs)         return wrapper     return _autoargs 

So when you say

class Foo(object):     @autoargs()     def __init__(self,x,path,debug=False,*args,**kw):         pass foo=Foo('bar','/tmp',True, 100, 101,verbose=True) 

you automatically get these instance attributes:

print(foo.x) # bar print(foo.path) # /tmp print(foo.debug) # True print(foo.args) # (100, 101) print(foo.verbose) # True 

PS. Although I wrote this (for fun), I don't recommend using autoargs for serious work. Being explicit is simple, clear and infallible. I can't say the same for autoargs.

PPS. Is it just me, or are a lot of buttons broken on Stackoverflow? The editor window has lost all its icons... :( Clearing the browser cache fixed the problem.

like image 119
unutbu Avatar answered Oct 11 '22 20:10

unutbu