python class 是否可以声明为与另一个 class(包括默认值)具有相同的 __init__() 签名?
Can a python class be declared to have the same __init__() signature as another class (including defaults)?
考虑以下包装器:
class SomeClass:
def __init__(arg1='default1', arg2='default2'):
# initialize stuff
def do_stuff(self):
class SomeClassWrapper:
def __init__(arg1='default1', arg2='default2'):
self.arg1 = arg1
self.arg2 = arg2
def doit(self):
instance = SomeClass(arg1, arg2)
instance.do_stuff()
SomeClassWrapper
用于延迟 SomeClass
对象的实例化,并在每次需要执行 do_stuff()
时抽象出新实例的创建。
SomeClassWrapper
使用稍后初始化 SomeClass
对象所需的“模板”进行初始化,这些对象的实际初始化列表比示例中的要长得多,并且会随着项目的发展而变化。
我们的目标是通过不必在 SomeClassWrapper.__init__()
中手动重新键入我们在 SomeClass.__init__()
.
中已有的相同参数列表(包括默认值)来减少错误和维护负担
有没有办法,也许使用 inspect
模块,按照下面的方式做一些事情?
class SomeClassWrapper:
# syntax to say:
# __init__() should be the same as SomeClass.__init__()
# the arguments should be stored in say self.kwargs
def doit(self)
instance = SomeClass(self.kwargs)
instance.do_stuff()
您可以将包装器用作您继承自的模板,并根据 class 您需要的包装器创建新的包装器。
class SomeClass:
def __init__(self, arg1='default1', arg2='default2'):
# Initialize stuff
def do_stuff(self):
# Do stuff
class AnotherClass:
def __init__(self, hello='a'):
# Initialize stuff
def do_stuff(self):
# Do stuff
class BaseClassWrapper:
instance_class = None
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def doit(self):
instance = self.instance_class(*self.args, **self.kwargs)
instance.do_stuff()
class SomeClassWrapper(BaseClassWrapper):
instance_class = SomeClass
class AnotherClassWrapper(BaseClassWrapper):
instance_class = AnotherClass
wrapper1 = SomeClassWrapper('arg1', arg2='arg2')
wrapper1.doit()
wrapper2 = AnotherClassWrapper('goodbye')
wrapper2.doit()
与其复制参数传递,不如让包装器接受创建对象的零参数可调用对象。
class SomeClass:
def __init__(arg1='default1', arg2='default2'):
# initialize stuff
def do_stuff(self):
...
class SomeClassWrapper:
def __init__(self, maker):
self.maker = maker
def doit(self):
instance = self.maker()
instance.do_stuff()
来电者仍然提供所有详细信息,但方式略有不同
# Old version
# w = SomeClassWrapper('foo', 'bar)
# One option
w = SomeClassWrapper(lambda: SomeClass('foo', 'bar'))
# Another option
from functools import partial
w = SomeClassWrapper(partial(SomeClass, 'foo', 'bar'))
考虑以下包装器:
class SomeClass:
def __init__(arg1='default1', arg2='default2'):
# initialize stuff
def do_stuff(self):
class SomeClassWrapper:
def __init__(arg1='default1', arg2='default2'):
self.arg1 = arg1
self.arg2 = arg2
def doit(self):
instance = SomeClass(arg1, arg2)
instance.do_stuff()
SomeClassWrapper
用于延迟 SomeClass
对象的实例化,并在每次需要执行 do_stuff()
时抽象出新实例的创建。
SomeClassWrapper
使用稍后初始化 SomeClass
对象所需的“模板”进行初始化,这些对象的实际初始化列表比示例中的要长得多,并且会随着项目的发展而变化。
我们的目标是通过不必在 SomeClassWrapper.__init__()
中手动重新键入我们在 SomeClass.__init__()
.
有没有办法,也许使用 inspect
模块,按照下面的方式做一些事情?
class SomeClassWrapper:
# syntax to say:
# __init__() should be the same as SomeClass.__init__()
# the arguments should be stored in say self.kwargs
def doit(self)
instance = SomeClass(self.kwargs)
instance.do_stuff()
您可以将包装器用作您继承自的模板,并根据 class 您需要的包装器创建新的包装器。
class SomeClass:
def __init__(self, arg1='default1', arg2='default2'):
# Initialize stuff
def do_stuff(self):
# Do stuff
class AnotherClass:
def __init__(self, hello='a'):
# Initialize stuff
def do_stuff(self):
# Do stuff
class BaseClassWrapper:
instance_class = None
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def doit(self):
instance = self.instance_class(*self.args, **self.kwargs)
instance.do_stuff()
class SomeClassWrapper(BaseClassWrapper):
instance_class = SomeClass
class AnotherClassWrapper(BaseClassWrapper):
instance_class = AnotherClass
wrapper1 = SomeClassWrapper('arg1', arg2='arg2')
wrapper1.doit()
wrapper2 = AnotherClassWrapper('goodbye')
wrapper2.doit()
与其复制参数传递,不如让包装器接受创建对象的零参数可调用对象。
class SomeClass:
def __init__(arg1='default1', arg2='default2'):
# initialize stuff
def do_stuff(self):
...
class SomeClassWrapper:
def __init__(self, maker):
self.maker = maker
def doit(self):
instance = self.maker()
instance.do_stuff()
来电者仍然提供所有详细信息,但方式略有不同
# Old version
# w = SomeClassWrapper('foo', 'bar)
# One option
w = SomeClassWrapper(lambda: SomeClass('foo', 'bar'))
# Another option
from functools import partial
w = SomeClassWrapper(partial(SomeClass, 'foo', 'bar'))