2017-08-17 92 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) 
相關問題