Mat*_*ner 11 python metaprogramming descriptor python-3.x
我有大约20种方法重定向到一个包装方法,该方法采用原始方法,其余的参数:
class my_socket(parent):
def _in(self, method, *args, **kwargs):
# do funky stuff
def recv(self, *args, **kwargs):
return self._in(super().recv, *args, **kwargs)
def recv_into(self, *args, **kwargs):
return self._in(super().recv_into, *args, **kwargs)
# and so on...
Run Code Online (Sandbox Code Playgroud)
如何以编程方式添加更多这些方法?一切都开始出错之前,这是我所能得到的:
for method in 'recv', 'recvfrom', 'recvfrom_into', 'recv_into', ...:
setattr(my_socket, method, ???)
Run Code Online (Sandbox Code Playgroud)
我可以通过在类定义中分配,还是其他感觉更自然的东西来做到这一点?
class my_socket(parent):
def makes_recv_methods(name):
# wraps call to name
def recv_meh = makes_recv_methods('recv_meh')
Run Code Online (Sandbox Code Playgroud)
我希望尽可能使用__get__和朋友一起使用魔术功能types.
我通过在定义类之后运行一些代码从列表生成方法来实现它 - 你可以把它放到装饰器中.
import functools
def wrap_method(cls, name):
# This unbound method will be pulled from the superclass.
wrapped = getattr(cls, name)
@functools.wraps(wrapped)
def wrapper(self, *args, **kwargs):
return self._in(wrapped.__get__(self, cls), *args, **kwargs)
return wrapper
def wrap_methods(cls):
for name in cls.WRAP_ATTRS:
setattr(cls, name, wrap_method(cls, name))
return cls
@wrap_methods
class my_socket(parent_class):
WRAP_ATTRS = ['recv', 'recvfrom'] # ... + more method names
def _in(self, method, *args, **kwargs):
# do funky stuff
Run Code Online (Sandbox Code Playgroud)