[英]Python decorator for automatic binding __init__ arguments
是否有自动绑定到方式self
(一些)的参数__init__
方法?
我的意思是这样的:
class Person:
@lazy_init
def __init__(self, name, age, address):
...
... 代替:
class Person:
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
...
我想知道人们在这种情况下是否已经使用了类似的东西。 或者有什么理由我不应该首先这样做?
这绝对是可能的,这是一个有点幼稚的实现:
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
一旦你开始拥有除了映射到属性的属性之外的东西,你就会遇到麻烦。 您至少需要某种方式来指定将哪些 args 初始化为属性......在这一点上它只会变得比它的价值更麻烦。
供将来遇到此问题的所有其他人参考(Python 3.7 或更高版本):有一个dataclass装饰器可以做到这一点。
from dataclasses import dataclass
@dataclass
class Person:
name
age
address
# other methods...
由我创建的 initify.py :) 它完全符合您的期望。
class Animal:
@init_args(exclude=["name"])
def __init__(self, name):
pass
或使用默认值:
class Animal:
@init_args
def __init__(self, name="Default name"):
pass
甚至排除继承:
class Dog(Animal):
@init_args(exclude=["name"])
def __init__(self, species):
pass
在这里,以最简单的形式:
def lazy_init(*param_names):
def ret(old_init):
def __init__(self, *args, **kwargs):
if len(args) > len(param_names):
raise TypeError("Too many arguments")
for k in kwargs:
if k not in param_names:
raise TypeError("Arg %r unexpected" % k)
for par, arg in zip(param_names, args):
setattr(self, par, arg)
for par, arg in kwargs.items():
setattr(self, par, arg)
old_init(*args, **kwargs)
return __init__
#
return ret
class Q(object):
@lazy_init("a", "b")
def __init__(self, *args, **kwargs):
print "Original init"
>>> q = Q(1, 2)
Original init
>>> q.a, q.b
(1, 2)
考虑制作一个类装饰器来覆盖__str__
。
您可以像这样使用 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()
两者都产生等效的 init 方法:
def __init__(self, var_1, var_2):
self.var_1 = var_1
self.var_2 = var_2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.