如何自动将__init__参数分配给属性?
有没有办法自动把__init__
方法的一些参数绑定到self
上呢?
比如说,我们有:
class Person:
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
...
能不能创建一个lazy_init
装饰器,让我们可以用这种方式来做呢?
class Person:
@lazy_init
def __init__(self, name, age, address):
...
有没有类似的技巧?或者说,有什么好的理由不这样尝试吗?
5 个回答
4
你可以使用Python 3.7引入的数据类,像这样:
from dataclasses import dataclass
@dataclass
class MyClass:
var_1: str
var_2: float
或者你也可以使用fastcore
库里的store_attr()
方法,像这样:
from fastcore.utils import store_attr
class MyClass:
def __init__(self, var_1, var_2):
store_attr()
这两种方法最终都会得到相同的初始化方法:
def __init__(self, var_1, var_2):
self.var_1 = var_1
self.var_2 = var_2
7
这绝对是可能的,这里有一个比较简单的实现方法:
from functools import wraps
def lazy_init(init):
import inspect
arg_names = inspect.getargspec(init)[0]
@wraps(init)
def new_init(self, *args):
for name, value in zip(arg_names[1:], args):
setattr(self, name, value)
init(self, *args)
return new_init
class Person:
@lazy_init
def __init__(self, name, age):
pass
p = Person("Derp", 13)
print p.name, p.age
不过,一旦你开始使用除了属性以外的东西来映射到属性上,你就会遇到一些麻烦。你至少需要一种方法来指定哪些参数要初始化为属性……到那时,这样做就会变得麻烦,可能不值得。
9
为了方便将来遇到这个问题的朋友们(Python 3.7 或更高版本):有一个叫做 dataclass 的装饰器,它正好可以做到这一点。
示例
from dataclasses import dataclass
@dataclass
class Person:
name
age
address
# other methods...