デフォルトの引数として使用したいのでself.format
、これはメソッドがインスタンス固有である必要があることを意味します(つまり、これをクラスレベルで定義する方法はありません)。__init__
代わりに、たとえば、クラス中に特定のメソッドを定義できます。ここで、インスタンス固有の属性にアクセスできます。
1つのアプローチは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')