python 成员变量不初始化,在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.

解决方案

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值