2017-08-17 89 views
0

我很新的Python和我目前正在使用Python 3.4子类namedtuple,__new__和__init__

现在,我显然敲我的头通过继承“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'作为期望的“类型名称”。然后我得到了,

TypeError: object.__init__() takes no parameters

(ノಠ益ಠ)ノ彡┻━┻


回到点,

  1. 我的代码工作,但我从PyCharm获取大量警告。

  2. 似乎绝对没有办法满足PyCharm。

所以,我很担心,我可能会被忽略的处理事情的Python化方式。如果我是,我希望我可以使用一些提示。

+0

我有点困惑,为什么你有'__init__'方法,但否则代码看起来很好。找到关于如何告诉PyCharm代码正常的文档,然后继续。 –

+0

无论pycharm说你的代码对我来说看起来并不矛盾,我不明白你为什么要这样做,而不是仅仅是'Aloe = namedtuple('芦荟',['name','color','loveliness'])'然后'芦荟=芦荟(** params)'。 – Goyo

+0

@Goyo我想扩展namedtuple,因为我想把更多的自定义方法下的子类与我的数据库进行通信。在这种情况下,你认为我正朝着正确的方向思考吗? –

回答

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中并被忽略。

如果你的数据库中的行会总是产生完全相同连续字典中右三个键,甚至没有一个工厂方法麻烦,只需直接使用namedtuple和上述**params语法:

Aloe(**params) 
相关问题