Kam*_*yar 8 python type-annotation
在使用带注释字段定义类/模块时,如何像函数中那样获取注释?
class Test:
def __init__(self):
self.x : int
t = Test()
Run Code Online (Sandbox Code Playgroud)
现在我需要从 getattr(t,'x')
使用基准Python,在不更改的定义的情况下,您无法做任何选择Test。最小的更改是在类级别注释属性:
class Test:
x: int
def __init__(self):
# define self.x or not, but it needn't be annotated again
Run Code Online (Sandbox Code Playgroud)
实际上,这很好。默认情况下,假定在类范围内的批注是指实例属性,而不是类属性(在类范围内分配值将创建类属性,但不对其进行注释);您必须显式地使用它typing.ClassVar来表示带注释的类型仅打算用作类属性。PEP 526关于类和实例变量注释的部分定义了这些行为;它们是您可以依靠的,而不仅仅是偶然的实现。
一旦你做到了这一点,typing.get_type_hints将返回{'x': int}两个Test和t在你的榜样情况。
虽然这是对自己够了,我会注意到,在很多这样的情况如今,只要你标注无论如何,你可以用简化代码的dataclasses模块,获得以最小的打字为您定义的注释和基本功能。适用于您的情况的简单替换代码为:
import dataclasses
@dataclasses.dataclass
class Test:
x: int
Run Code Online (Sandbox Code Playgroud)
尽管您的手机壳没有展示完整的功能集(基本上只是用__init__装饰器代替了),但它的作用还远远不止于此。除了__init__为您定义(它希望收到一个带有x注释的参数int)以及一个合适的__repr__和之外__eq__,您还可以轻松定义默认值(只需在注释点或更复杂或易变的情况下分配默认值,分配一个dataclasses.field替代值),然后您可以传递参数dataclass以使其产生可排序或不可变的实例。
在您的情况下,主要优点是消除冗余;x注释和引用只进行一次,而不是在类级别进行一次注释,然后在初始化期间使用(并且可选地,再次进行注释)。
我不确定您是否可以self.x轻松获得注释。
假设你的代码:
class Test:
def __init__(self):
self.x: int = None
t = Test()
Run Code Online (Sandbox Code Playgroud)
我尝试寻找__annotations__inTest和t(我期望它在哪里),但运气不佳。
但是,您可以采取以下解决方法:
class Test:
x: int
def __init__(self):
# annotation from here seems to be unreachable from `__annotations__`
self.x: str
t = Test()
print(Test.__annotations__)
# {'x': <class 'int'>}
print(t.__annotations__)
# {'x': <class 'int'>}
Run Code Online (Sandbox Code Playgroud)
如果您希望能够检查@ruohola 的检查答案self.x内的类型。mypy
请注意,mypy(至少 v.0.560)确实会x因为从 theclass和 从 the进行注释而感到困惑__init__,即,看起来 的注释self.x被大胆地忽略了:
import sys
class Test:
x: str = "0"
def __init__(self):
self.x: int = 1
t = Test()
print(Test.x, t.x)
# 0 1
print(Test.x is t.x)
# False
if "mypy" in sys.modules:
reveal_type(t.x)
# from mypyp: annotated_self.py:14: error: Revealed type is 'builtins.str'
reveal_type(Test.x)
# from mypy: annotated_self.py:15: error: Revealed type is 'builtins.str'
Test.x = 2
# from mypy: annotated_self.py:17: error: Incompatible types in assignment (expression has type "int", variable has type "str")
t.x = "3"
# no complaining from `mypy`
t.x = 4
# from mypy: annotated_self.py:19: error: Incompatible types in assignment (expression has type "int", variable has type "str")
print(Test.x, t.x)
# 2 4
Run Code Online (Sandbox Code Playgroud)