在输入时使用typing.Any和object有什么不同吗?例如:
def get_item(L: list, i: int) -> typing.Any:
return L[i]对比:
def get_item(L: list, i: int) -> object:
return L[i]发布于 2016-10-02 20:43:20
是的,这是有区别的。虽然在Python3中,所有对象都是object的实例,包括object本身,但只有Any文档指出类型检查器应该忽略返回值。
Any类型文档字符串声明对象是Any子类,反之亦然:
>>> import typing
>>> print(typing.Any.__doc__)
Special type indicating an unconstrained type.
- Any object is an instance of Any.
- Any class is a subclass of Any.
- As a special case, Any and object are subclasses of each other.然而,一个合适的类型检查器(一个超越isinstance()检查的类型检查器,它检查对象在函数中的实际使用情况)可以很容易地反对始终接受Any的object。
请注意,将
Any类型的值赋给更精确的类型时,不会执行类型检查。
和
将
Any的行为与object的行为进行对比。与Any类似,每种类型都是object的子类型。然而,与Any不同的是,事实并非如此: object并不是所有其他类型的子类型。
这意味着当值的类型为object时,类型检查器将拒绝几乎所有对它的操作,并且将其赋给更专用类型的变量(或将其用作返回值)是一个类型错误。
和来自mypy文档部分的。
类型
object是另一种类型,它可以将任意类型的实例作为值。与Any不同,object是一个普通的静态类型(类似于Java语言中的Object),并且只接受对所有类型有效的对象值操作。
object可以被cast到一个更具体的类型,而Any实际上意味着任何事情都会发生,类型检查器会从对象的任何使用中解脱出来(即使您后来将这样的对象分配给一个类型检查的名称)。
通过接受与List[Any]相同的list,您已经将您的函数绘制到了一个无类型的角落。类型检查器在那里被释放,返回值不再重要,但是因为您的函数接受包含Any对象的列表,所以在这里适当的返回值应该是Any。
要正确地参与类型检查代码,您需要将输入标记为List[T] (一个通用类型的容器),以便类型检查器能够关心返回值。在您的示例中,它应该是T,因为您要从列表中检索值。从TypeVar创建T
from typing import TypeVar, List
T = TypeVar('T')
def get_item(L: List[T], i: int) -> T:
return L[i]发布于 2016-10-03 04:37:10
Any和object表面上很相似,但实际上在含义上完全相反。
object是Python元类层次结构的根。每个单独的类都继承自object。这意味着在某种意义上,object是您可以赋予值的最具限制性的类型。如果你有一个object类型的值,那么你唯一被允许调用的方法就是那些属于每个单独对象的方法。例如:
foo = 3 # type: object
# Error, not all objects have a method 'hello'
bar = foo.hello()
# OK, all objects have a __str__ method
print(str(foo)) 相反,Any是一个允许您混合使用动态和静态类型代码的逃生舱。Any是限制最少的类型--允许对Any类型的值执行任何可能的方法或操作。例如:
from typing import Any
foo = 3 # type: Any
# OK, foo could be any type, and that type might have a 'hello' method
# Since we have no idea what hello() is, `bar` will also have a type of Any
bar = foo.hello()
# Ok, for similar reasons
print(str(foo))通常情况下,您应该尝试并仅在以下情况下使用Any:
Dict[str, Any]类型,这总比没有好一点。相反,如果您希望以一种类型安全的方式指示某个值必须与任何可能存在的对象协同工作,请使用object。
我的建议是避免使用Any,除非在别无选择的情况下。Any是一种让步--一种允许我们真正生活在类型安全世界中的动态性的机制。
有关详细信息,请参阅:
对于您的特定示例,我将使用TypeVars,而不是object或Any。您想要做的是指示您希望返回列表中包含的任何内容的类型。如果列表将始终包含相同的类型(通常是这种情况),则需要执行以下操作:
from typing import List, TypeVar
T = TypeVar('T')
def get_item(L: List[T], i: int) -> T:
return L[i]这样,您的get_item函数将尽可能返回最精确的类型。
https://stackoverflow.com/questions/39817081
复制相似问题