run
基本クラスの関数をオーバーライドする関数を使用して、Python3.7でクラスを開発しています。run()
機能は例えば、引数の正確な数で定義する必要がありdef run(self, a, b)
、それが定義されていますどのように多くの引数に基づいて異なる動作をします-関数が呼び出されたときにその署名は、関数に右引数の数を提供するために、検査が行われます。私の設計では、引数の数(および名前)は、インスタンスが構築されるときにクラスに渡されます。
私は、次のようなモジュールを見下ろしていましたしないてきたfunctools
などのソリューション*args
と**kwargs
、しかし、私は彼らが私のシナリオでは動作しません恐れて、私は「バインド」にしたくないので、関数を呼び出す前に、任意の変数、どちらも私は可変引数リストをしたいですか。関数の引数の固定リストが必要ですが、クラスに提供されている変数を使用して関数を定義する必要があります:)
私の期待する結果を表示する方がおそらくはるかに簡単です。
>>>args1 = ['arg1', 'arg2']
>>>args2 = ['arg1', 'arg2', 'arg3']
...
...
>>>c1 = MyClass(run_args=args1)
>>>c2 = MyClass(run_args=args2)
>>>import inspect
>>>inspect.getargspec(c1.run)
ArgSpec(args=['self', 'arg1', 'arg2'], varargs=None, keywords=None, defaults=None)
>>>inspect.getargspec(c2.run)
ArgSpec(args=['self', 'arg1', 'arg2', 'arg3'], varargs=None, keywords=None, defaults=None)
同じクラスのオブジェクトは共通のメソッド、つまり共通のメソッドシグネチャを共有することが期待されるため、これはかなり奇妙な設計です。
ただし、Python3では、すべてのオブジェクトがメソッド名を使用して属性を定義でき、その属性はイディオムobj.method(args)
が呼び出されたときに使用されます。そして、その属性が関数またはラムダである場合、シグネチャを持つことができます。
コンセプトを示すミニマリストコードは次のとおりです。
import abc
import inspect
class Base(metaclass=abc.ABCMeta):
@abc.abstractmethod
def run(self, *args):
"""Just an example to show what arguments have been passed"""
print("run method called with", *args)
class Child(Base):
def __init__(self, run_args):
"""run_args is the list of the names of the arguments of run"""
params = [inspect.Parameter(n, inspect.Parameter.POSITIONAL_OR_KEYWORD)
for n in run_args]
# self.run is a lambda calling Child.run, but has a specific signature
self.run = lambda *args: Child.run(self, *args)
self.run.__signature__ = inspect.Signature(params)
def run(self, *args):
# controls that the signature of self.run has been observed
inspect.signature(self.run).bind(*args)
# do the processing - here only call the base class method
super().run(*args)
これで、テストできます。
>>> c1 = Child(['arg1', 'arg2'])
>>> c1.run(1,2)
run method called with 1 2
>>> c1.run(1,2,3)
Traceback (most recent call last):
...
TypeError: too many positional arguments
>>> c1.run(1)
Traceback (most recent call last):
File "<pyshell#119>", line 1, in <module>
...
TypeError: missing a required argument: 'arg2'
>>> c2 = Child(['arg1', 'arg2', 'arg3'])
>>> c2.run(1,2,3)
run method called with 1 2 3
>>> c1.run(1,2)
run method called with 1 2
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加