由于您想将其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('custom') # Doesn't work!
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')