我的许多课程看起来像以下课程来代表帐户
class Account(object):
def __init__(self, first, last, age, id, balance):
self.first = first
self.last = last
self.age = age
self.id = id
self.balance = balance
def _info(self):
return self.first, self.last, self.age, self.id, self.balance
def __eq__(self, other):
return self._info == other._info()
def __hash__(self):
return hash((type(self), self.info()))
def ... # other methods follow
但实际上唯一相关的信息是我关心的first, last, age, id, balance
属性列表。是否有一种标准方法来定义遵循此结构的Python类?
乍一看,我想到namedtuple
,但我不确定这是否允许我在事后添加其他方法。真的,我想要类似下面的内容
class Account(object):
attributes = "first last age id balance"
def ... # other methods
获得此项的最佳方式是什么?
答案 0 :(得分:3)
不确定它是多么惯用,但以下内容满足您的要求:
class Slottable:
def __init__(self, *args):
for slot, arg in zip(self.slots.split(' '), args):
setattr(self, slot, arg)
def _info(self):
return tuple(getattr(self, attr) for attr in self.slots.split())
def __eq__(self, other):
return self._info() == other._info()
def __hash__(self):
return hash((type(self), self._info()))
class Account(Slottable):
slots = "first last age id balance"
def fullname(self):
return self.first + " " + self.last
matt = Account("Matthew", "Smith", 28, 666, 1E6)
john = Account("John", "Jones", 46, 667, 1E7)
d = {matt: 5, john: 6} # Hashable
print matt.fullname()
#=> "Matthew Smith"
print john.fullname()
#=> "John Jones"
print matt == matt, matt == john
#=> True False
matt.age = 29 # Happy birthday!
print matt.age
#=> 29
答案 1 :(得分:1)
Here are some recipes you can try:覆盖__setattr__
,__dict__
,__slots__
和/或init
。让我们知道什么对你有用。
答案 2 :(得分:0)
目前有许多图书馆可以满足这种需求:attrs
,dataclasses
,pydantic
,...以及我对此景观的新添加pyfields
。
选择主要取决于您需要或不需要的功能。 pyfields
专注于字段定义以及可选的验证和转换,而对您的类没有 any 约束。 可以成为本地的字段变得与python native属性一样快,而需要回调(验证器/转换器)的字段则使用描述符来实现。
您可以将自己的构造函数与
混合from pyfields import field, init_fields
class Account(object):
first = field(doc="first name")
last = field(doc="last name")
age = field(doc="the age in years")
id = field(doc="an identifier")
balance = field(doc="current balance in euros")
@init_fields
def __init__(self, msg):
print(msg)
a = Account("hello, world!", first="s", last="marie", age=135, id=0, balance=-200000)
print(vars(a))
收益
hello, world!
{'balance': -200000, 'id': 0, 'age': 135, 'last': 'marie', 'first': 's'}
pyfields
与其他更多的“多合一”库相反,仅以“最小可行产品”精神集中于字段和构造函数。因此,如果您还希望dict表示和转换,哈希,相等和比较,则应使用另一个库将它们添加到类的顶部。我目前正在开发mixture
库,为此提供混合类,并具有点菜功能的相同哲学-无论有无{{1} }。
有关详细信息,请参见pyfields
documentation。不要犹豫,提供反馈!