注解最佳实践 ¶
- 作者 :
-
Larry Hastings
访问 Python 3.10 及更新版本的对象注解字典 ¶
Python 3.10 向标准库添加了新函数:
inspect.get_annotations()
. In Python versions 3.10 and newer, calling this function is the best practice for accessing the annotations dict of any object that supports annotations. This function can also “un-stringize” stringized annotations for you.
If for some reason
inspect.get_annotations()
isn’t viable for your use case, you may access the
__annotations__
data member manually. Best practice for this changed in Python 3.10 as well: as of Python 3.10,
o.__annotations__
is guaranteed to
always
work on Python functions, classes, and modules. If you’re certain the object you’re examining is one of these three
specific
objects, you may simply use
o.__annotations__
to get at the object’s annotations dict.
However, other types of callables–for example, callables created by
functools.partial()
–may not have an
__annotations__
attribute defined. When accessing the
__annotations__
of a possibly unknown object, best practice in Python versions 3.10 and newer is to call
getattr()
with three arguments, for example
getattr(o, '__annotations__', None)
.
Before Python 3.10, accessing
__annotations__
on a class that defines no annotations but that has a parent class with annotations would return the parent’s
__annotations__
. In Python 3.10 and newer, the child class’s annotations will be an empty dict instead.
访问 Python 3.9 及更旧版本的对象注解字典 ¶
In Python 3.9 and older, accessing the annotations dict of an object is much more complicated than in newer versions. The problem is a design flaw in these older versions of Python, specifically to do with class annotations.
Best practice for accessing the annotations dict of other objects–functions, other callables, and modules–is the same as best practice for 3.10, assuming you aren’t calling
inspect.get_annotations()
: you should use three-argument
getattr()
to access the object’s
__annotations__
属性。
Unfortunately, this isn’t best practice for classes. The problem is that, since
__annotations__
is optional on classes, and because classes can inherit attributes from their base classes, accessing the
__annotations__
attribute of a class may inadvertently return the annotations dict of a
基类。
As an example:
class Base: a: int = 3 b: str = 'abc' class Derived(Base): pass print(Derived.__annotations__)