如何使用静态检查来确保对象具有特定的方法/属性? [英] How can I use static checking to ensure an object has a certain method/attribute?
问题描述
有没有办法可以注释函数以确保传递给函数的对象具有特定的方法或属性,但我不关心它的实际类型?
Is there I way that I can annotate a function to ensure that an object being passed into the function has a certain method or attribute, but where I don't care about its actual type?
Pycharm 在内部使用类似于 {b}
的语法来指示它推断出的对象需要哪些方法/属性,但这似乎不是有效的 Python 语法:
Pycharm internally uses a syntax that looks like {b}
to indicate what methods/attributes it's inferred are required for the object, but that doesn't appear to be valid Python syntax:
def func(a: {b}): # Error
a.b = 1
有没有办法让类型检查器帮助鸭子打字,我只关心对象有什么方法/属性,而不关心对象的类型是什么,我不能修改我想要的类型检查?
Is there a way to get the type checker to assist in duck typing, where I only care what methods/attributes the object has, not what the type of the objects are, and where I can't modify the types I want to check for?
推荐答案
Protocol
s 可以使用.我在这里记录它是因为我发现这是一个很难搜索的话题;特别是检查属性是否存在.
Protocol
s can be used. I'm documenting it here because I found this to be a difficult topic to search for; especially checking for the existence of attributes.
为了确保属性的存在:
from typing import Protocol
class HasFoo(Protocol): # Define what's required
foo: int
class Foo: # This class fulfills the protocol implicitly
def __init__(self):
self.foo = 1
class Bar:
def __init__(self): # This class fails to implicitly fulfill the protocol
self.bar = 2
def foo_func(f: HasFoo):
pass
foo_func(Foo()) # Type check succeeds
foo_func(Bar()) # Type check fails
注意foo
后面的类型提示.该行必须在语法上有效,并且类型必须与已检查属性的推断类型相匹配.typing.Any
可以用作占位符,如果您关心 foo
的存在,而不是它的类型.
Note the type hint after foo
. It's required for that line to be syntactically valid, and the type must match the inferred type of the checked attributes. typing.Any
can be used as a placeholder if you care about the existence of foo
, but not its type.
同样,检查方法也可以这样做:
Similarly, the same can be done for checking methods:
class HasFoo(Protocol):
def foo(self):
pass
class Foo:
def foo(self):
pass
class Bar:
def bar(self):
pass
def func(f: HasFoo):
pass
func(Foo()) # Succeeds
func(Bar()) # Fails
类型检查是通过Pycharm 2020.2.2
完成的.
这篇关于如何使用静态检查来确保对象具有特定的方法/属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!