正如其他人所提到的,重复并不坏,但在某些情况下,命名元组可能非常适合这种类型的问题。这样可以避免使用 local ()或 kwargs,这通常是个坏主意。
from collections import namedtuple
# declare a new object type with three properties; x y z
# the first arg of namedtuple is a typename
# the second arg is comma-separated or space-separated property names
XYZ = namedtuple("XYZ", "x, y, z")
# create an object of type XYZ. properties are in order
abc = XYZ("one", "two", 3)
print abc.x
print abc.y
print abc.z
我发现它的用途有限,但是您可以像继承任何其他对象一样继承 namedtuple (示例继续) :
class MySuperXYZ(XYZ):
""" I add a helper function which returns the original properties """
def properties(self):
return self.x, self.y, self.z
abc2 = MySuperXYZ(4, "five", "six")
print abc2.x
print abc2.y
print abc2.z
print abc2.properties()
class X:
x = None
y = None
z = None
def __init__(self, **kwargs):
for (k, v) in kwargs.items():
if hasattr(self, k):
setattr(self, k, v)
else:
raise TypeError('Unknown keyword argument: {:s}'.format(k))
def auto_init(local_name_space):
"""Set instance attributes from arguments.
"""
self = local_name_space.pop('self')
for name, value in local_name_space.items():
setattr(self, name, value)
申请
你需要用 locals()调用它:
class A:
def __init__(self, x, y, z):
auto_init(locals())
测试
a = A(1, 2, 3)
print(a.__dict__)
产出:
{'y': 2, 'z': 3, 'x': 1}
不改变 locals()
如果你不喜欢改变 locals()使用这个版本:
def auto_init(local_name_space):
"""Set instance attributes from arguments.
"""
for name, value in local_name_space.items():
if name != 'self':
setattr(local_name_space['self'], name, value)
该模块提供了一个修饰符和函数,用于自动将生成的特殊方法(如 __init__()和 __repr__())添加到用户定义的类中。它最初是在 PEP 557中描述的。
在这些生成的方法中使用的成员变量是使用 PEP 526类型注释定义的:
@dataclass
class InventoryItem:
'''Class for keeping track of an item in inventory.'''
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand