2017-06-20 88 views
3

當我定義一個類時,如何在其方法的簽名中包含參數,而這些參數必須是同一類?我建立它應該像這樣的圖形結構,但這裏是一個簡單的例子:類型(方法)的方法簽名參數

class Dummy: 
    def __init__(self, value: int, previous: Dummy=None): 
     self._value = value 
     self._previous = previous 

    @property 
    def value(self): 
     return self._value 

    def plus_previous(self): 
     return self.value + self._previous.value 

d1 = Dummy(7) 
d2 = Dummy(3, d1) 
d2.plus_previous() 

這將導致以下錯誤:

NameError: name 'Dummy' is not defined 

我的意思是,我能做到這一點了Python 2的方式,但我希望有比這更蟒蛇-3-IC解決方案:

class Dummy: 
    def __init__(self, value: int, previous=None): 
     assert type(previous) is Dummy or previous is None 
     ... 
+0

PS:很明顯,我不能使用: 類型(個體經營) 自我未簽名沒有定義。我只能這樣做: assert type(previous)is type(self) 這至少是一個小改進 –

+0

另外,你意識到類型提示不會像'assert'語句那樣工作,對嗎?他們沒有執行。他們是*提示*。 –

回答

2

雖然我同意,這是一個相當難看黑客,您可以使用字符串類型提示以及:

class Dummy: 
    def __init__(self, value: int, previous: 'Dummy'=None): 
     self._value = value 
     self._previous = previous 

    @property 
    def value(self): 
     return self._value 

    def plus_previous(self): 
     return self.value + self._previous.value
如在 PEP-484在類型提示描述

When a type hint contains names that have not been defined yet, that definition may be expressed as a string literal, to be resolved later.

A situation where this occurs commonly is the definition of a container class, where the class being defined occurs in the signature of some of the methods. For example, the following code (the start of a simple binary tree implementation) does not work:

class Tree: 
    def __init__(self, left: Tree, right: Tree): 
     self.left = left 
     self.right = right 

To address this, we write:

class Tree: 
    def __init__(self, left: 'Tree', right: 'Tree'): 
     self.left = left 
     self.right = right 

The string literal should contain a valid Python expression (i.e., compile(lit, '', 'eval') should be a valid code object) and it should evaluate without errors once the module has been fully loaded. The local and global namespace in which it is evaluated should be the same namespaces in which default arguments to the same function would be evaluated.

用這個技巧的問題不過是,如果你在IDE做重命名,它是絕對有可能IDE不會考慮這些字符串文字,從而無法重新命名這些文字。

相關問題