子类化namedtuple,__ new__和__init__

时间:2017-08-17 08:38:51

标签: python inheritance namedtuple

我是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__()被指责为“参数”类型名称“未填充

所以我给了它一个好的'Plant'作为所需的'typename'。然后我得到了,

TypeError: object.__init__() takes no parameters

(ノಠ益ಠ)ノ彡┻━┻

回到这一点,

  1. 我的代码正在运行,但我从PyCharm收到大量警告。

  2. 我似乎无法满足PyCharm。

  3. 所以,我担心我可能会忽略 Pythonic 处理事物的方式。如果我是,我希望我可以使用一些技巧。

1 个答案:

答案 0 :(得分:2)

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)