Dav*_*aub 6 python design-patterns python-typing
我有一个带有底层对象的代理类。我希望将代理对象传递给需要底层对象类型的函数。如何使代理类型与底层对象匹配?
class Proxy:
def __init__(self, obj):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Warning: expected 'MyClass', got 'Proxy' instead
Run Code Online (Sandbox Code Playgroud)
感谢@SUTerliakov 在问题评论中实际提供了这个答案的本质。该代码应类似于以下内容:
from typing import TYPE_CHECKING
from my_module import MyClass
if TYPE_CHECKING:
base = MyClass
else:
base = object
class Proxy(base):
def __init__(self, obj):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Works!
Run Code Online (Sandbox Code Playgroud)
请注意,您的课程可能并不总是可用 - 但这不是真正的问题。这个技巧与 TypeVars 配合得非常好。
# proxy.py
from typing import TYPE_CHECKING, TypeVar
Proxied = TypeVar('Proxied')
if TYPE_CHECKING:
base = Proxied
else:
base = object
class Proxy(base):
def __init__(self, obj: Proxied):
self.obj = obj
def __getattribute__(self, name):
return getattr(self.obj, name)
def __setattr__(self, name, value):
setattr(self.obj, name, value)
Run Code Online (Sandbox Code Playgroud)
在使用它的文件中:
from proxy import Proxy
def foo(bar: MyClass):
...
foo(Proxy(MyClass())) # Works!
Run Code Online (Sandbox Code Playgroud)