由于您要self.format
用作默认参数,因此这意味着该方法需要特定于实例(即无法在类级别定义此方法)。相反,您可以在上课期间定义特定的方法__init__
。在这里,您可以访问实例特定的属性。
一种方法是使用functools.partial
以获得该方法的更新(特定)版本:
from functools import partial
class C:
def __init__(self, format):
self.format = format
self.process = partial(self.process, formatting=self.format)
def process(self, formatting):
print(formatting)
c = C('default')
c.process()
c.process(formatting='custom')
请注意,使用这种方法只能通过关键字传递相应的参数,因为如果按位置提供参数,则会在 partial
。
另一种方法是在以下方法中定义和设置方法__init__
:
from types import MethodType
class C:
def __init__(self, format):
self.format = format
def process(self, formatting=self.format):
print(formatting)
self.process = MethodType(process, self)
c = C('test')
c.process()
c.process('custom')
c.process(formatting='custom')
这也允许按位置传递参数,但是方法的解析顺序变得不太明显(例如,这可能会影响IDE检查,但是我想有针对此的IDE专用解决方法)。
另一种方法是为这些“实例属性默认值”创建一个自定义类型,以及一个执行相应getattr
参数填充的特殊装饰器:
import inspect
class Attribute:
def __init__(self, name):
self.name = name
def decorator(method):
signature = inspect.signature(method)
def wrapper(self, *args, **kwargs):
bound = signature.bind(*((self,) + args), **kwargs)
bound.apply_defaults()
bound.arguments.update({k: getattr(self, v.name) for k, v in bound.arguments.items()
if isinstance(v, Attribute)})
return method(*bound.args, **bound.kwargs)
return wrapper
class C:
def __init__(self, format):
self.format = format
@decorator
def process(self, formatting=Attribute('format')):
print(formatting)
c = C('test')
c.process()
c.process('custom')
c.process(formatting='custom')