子类化 namedtuple,__new__ 和 __init__
Subclassing namedtuple, __new__ and __init__
我是 Python 的新手,目前正在使用 Python 3.4
现在,我显然正在绞尽脑汁想弄清楚如何通过子类化 'namedtuple'.
来最好地创建自定义的不可变对象
这是我的代码,可以正常运行,但是我从我的好朋友 PyCharm 那里收到了太多警告消息,所以我被要求检查我是否正确地执行了此操作。
from collections import namedtuple
class Aloe(namedtuple('Plant', [
'name',
'color',
'loveliness'
])):
def __new__(cls, params):
return super(Aloe, cls).__new__(
cls,
params.get('name'),
params.get('color'),
params.get('loveliness')
)
def __init__(self, params):
print(self.name)
super(Aloe, self).__init__()
当我调用它时,我得到了这个。
>>> aloe = Aloe(params)
>>> print(aloe)
Aloe(name='aloey', color='green', loveliness='extreme')
第一个警告来自 __new__
块。
我所有的 params.get('FIELD_NAME')
都被指责为“意外参数”。
有趣的是,如果我删除参数,我得到了,
TypeError: __new__() missing 1 required positional argument:
这东西到底要我做什么?!
第二个警告来自 __init__
块。
super(Aloe, self).__init__()
被指责为“参数 'typename' 未填充”
所以我给了它一个很好的'Plant'
作为期望'typename'。然后我得到了,
TypeError: object.__init__() takes no parameters
(ノಠ益ಠ)ノ彡┻━┻
言归正传,
我的代码可以正常工作,但我收到来自 PyCharm 的大量警告。
看来我完全无法满足PyCharm.
所以,我担心我可能忽略了 Pythonic 处理事情的方式。如果我是,我希望我可以使用一些技巧。
PyCharm 在这里保护过度,引导不正确。但是,如果您只想提供一些默认值,我会使用工厂方法:
class Aloe(namedtuple('Plant', 'name color loveliness')):
@classmethod
def from_row(cls, name=None, color=None, loveliness=None, **ignored):
return cls(name, color, loveliness)
并在创建时使用 **params
:
Aloe.from_row(**params)
这会将 params
中的键值对应用为单独的关键字参数。缺少的键将设置为 None
,额外的键将在 **ignored
中捕获并忽略。
如果您的数据库行总是在行字典中生成完全正确的 3 个键,甚至不用费心使用工厂方法,直接使用 namedtuple
和上面的 **params
语法:
Aloe(**params)
我是 Python 的新手,目前正在使用 Python 3.4
现在,我显然正在绞尽脑汁想弄清楚如何通过子类化 'namedtuple'.
来最好地创建自定义的不可变对象这是我的代码,可以正常运行,但是我从我的好朋友 PyCharm 那里收到了太多警告消息,所以我被要求检查我是否正确地执行了此操作。
from collections import namedtuple
class Aloe(namedtuple('Plant', [
'name',
'color',
'loveliness'
])):
def __new__(cls, params):
return super(Aloe, cls).__new__(
cls,
params.get('name'),
params.get('color'),
params.get('loveliness')
)
def __init__(self, params):
print(self.name)
super(Aloe, self).__init__()
当我调用它时,我得到了这个。
>>> aloe = Aloe(params)
>>> print(aloe)
Aloe(name='aloey', color='green', loveliness='extreme')
第一个警告来自
__new__
块。
我所有的 params.get('FIELD_NAME')
都被指责为“意外参数”。
有趣的是,如果我删除参数,我得到了,
TypeError: __new__() missing 1 required positional argument:
这东西到底要我做什么?!
第二个警告来自
__init__
块。
super(Aloe, self).__init__()
被指责为“参数 'typename' 未填充”
所以我给了它一个很好的'Plant'
作为期望'typename'。然后我得到了,
TypeError: object.__init__() takes no parameters
(ノಠ益ಠ)ノ彡┻━┻
言归正传,
我的代码可以正常工作,但我收到来自 PyCharm 的大量警告。
看来我完全无法满足PyCharm.
所以,我担心我可能忽略了 Pythonic 处理事情的方式。如果我是,我希望我可以使用一些技巧。
PyCharm 在这里保护过度,引导不正确。但是,如果您只想提供一些默认值,我会使用工厂方法:
class Aloe(namedtuple('Plant', 'name color loveliness')):
@classmethod
def from_row(cls, name=None, color=None, loveliness=None, **ignored):
return cls(name, color, loveliness)
并在创建时使用 **params
:
Aloe.from_row(**params)
这会将 params
中的键值对应用为单独的关键字参数。缺少的键将设置为 None
,额外的键将在 **ignored
中捕获并忽略。
如果您的数据库行总是在行字典中生成完全正确的 3 个键,甚至不用费心使用工厂方法,直接使用 namedtuple
和上面的 **params
语法:
Aloe(**params)