2016-03-24 8 views
9

में टाइप एनोटेशन का स्व-संदर्भ मैं यह जानने का प्रयास कर रहा हूं कि python3's type annotations के साथ प्रकारों का आत्म-संदर्भ कैसे काम करता है - दस्तावेज़ इस बारे में कुछ भी निर्दिष्ट नहीं करते हैं।पायथन

एक उदाहरण के रूप:

from typing import TypeVar, Optional, Generic 

T = TypeVar('T') 
class Node(Generic[T]): 
    left = None 
    right = None 
    value = None 

    def __init__(
     self, value: Optional[T], 
     left: Optional[Node[T]]=None, 
     right: Optional[Node[T]]=None, 
    ) -> None: 
     self.value = value 
     self.left = left 
     self.right = right 

इस कोड त्रुटि उत्पन्न:

Traceback (most recent call last): 
    File "node.py", line 4, in <module> 
    class Node(Generic[T]): 
    File "node.py", line 12, in Node 
    right: Optional[Node[T]]=None, 
NameError: name 'Node' is not defined 

यह अजगर 3.5.1

+0

हममम, 'typing' उपलब्ध केवल 3.5 से है। जांचें [3.5 संस्करण का क्या नया] [https://docs.python.org/3.5/whatsnew/3.5.html) – thefourtheye

+0

@thefourtheye: मैंने सवाल संपादित किया। मैंने अभी 3.5.1 स्थापित किया है और समस्या अभी भी मौजूद है। 3.4 के साथ काम करने का कारण यह था क्योंकि मेरे पास – LiraNuna

उत्तर

14

PEP 0484 - Type Hints - The problem of forward declarations पतों का उपयोग कर रहा है मुद्दा:

The problem with type hints is that annotations (per PEP 3107 , and similar to default values) are evaluated at the time a function is defined, and thus any names used in an annotation must be already defined when the function is being defined. A common scenario is a class definition whose methods need to reference the class itself in their annotations. (More general, it can also occur with mutually recursive classes.) This is natural for container types, for example:

...

As written this will not work, because of the peculiarity in Python that class names become defined once the entire body of the class has been executed. Our solution, which isn't particularly elegant, but gets the job done, is to allow using string literals in annotations. Most of the time you won't have to use this though -- most uses of type hints are expected to reference builtin types or types defined in other modules.

from typing import TypeVar, Optional, Generic 

T = TypeVar('T') 
class Node(Generic[T]): 
    left = None 
    right = None 
    value = None 

    def __init__(
     self, 
     value: Optional[T], 
     left: Optional['Node[T]']=None, 
     right: Optional['Node[T]']=None, 
    ) -> None: 
     self.value = value 
     self.left = left 
     self.right = right 

>>> import typing 
>>> typing.get_type_hints(Node.__init__) 
{'return': None, 
'value': typing.Union[~T, NoneType], 
'left': typing.Union[__main__.Node[~T], NoneType], 
'right': typing.Union[__main__.Node[~T], NoneType]} 
+0

इंस्टॉल किया गया था! मुझे विश्वास नहीं है कि मैं उस हिस्से को पूरी तरह से याद करता हूं - यह मेरे लिए भी एक समान उदाहरण है! – LiraNuna

+0

जीसस ... अच्छा, यह कुछ भी नहीं है, मुझे लगता है। धन्यवाद –