Python 如何使用'functools.partial()向类动态添加方法`
在以下情况下,使用Python 如何使用'functools.partial()向类动态添加方法`,python,functools,partial-application,Python,Functools,Partial Application,在以下情况下,使用functools.partial将动态方法添加到类中时,我遇到了正确的咒语问题。下面有一个Creator类,我想向其中添加一个create\u someclass方法,该方法由Creator类状态部分参数化 import functools class Creator: def __init__(self, params): self.params = params class Stitch: __tablename__ = 'stitch
functools.partial
将动态方法添加到类中时,我遇到了正确的咒语问题。下面有一个Creator
类,我想向其中添加一个create\u someclass
方法,该方法由Creator
类状态部分参数化
import functools
class Creator:
def __init__(self, params):
self.params = params
class Stitch:
__tablename__ = 'stitch'
def __init__(self, params, name):
self.name = name
self.params = params
def create(self, clz, *args, **kwargs):
return clz(self.params, *args, **kwargs)
for clazz in [Stitch]:
setattr(Creator, 'create_%s' % clazz.__tablename__, functools.partial(create, clz=clazz))
creator = Creator('params')
# Neither of these work, but I'd like either one -- preferably the first one.
stitch = creator.create_stitch('myname')
# AttributeError: 'str' object has no attribute 'params'
stitch = creator.create_stitch(name='myname')
# TypeError: create() missing 1 required positional argument: 'self'
对于类方法来说,这是一个问题,因此在Python3.4中我们引入了
partialmethod
。其工作方式如下:
import functools
class Creator:
def __init__(self, params):
self.params = params
class Stitch:
__tablename__ = 'stitch'
def __init__(self, params, name):
self.name = name
self.params = params
def create(self, clz, *args, **kwargs):
return clz(self.params, *args, **kwargs)
for clazz in [Stitch]:
setattr(Creator, 'create_%s' % clazz.__tablename__, functools.partialmethod(create, clz=clazz))
# use partialmethod instead here
creator = Creator('params')
stitch = creator.create_stitch(name='myname')
# works!
我认为问题在于
create
是Stitch的一个成员函数(尽管缩进不好:create
访问Stitch
的成员变量params
),因此需要Stitch
类型的对象才能与create
一起使用,然后,它也将作为第一个参数传递给create
。它的工作原理如下:
import functools
class Creator:
def __init__(self, params):
self.params = params
class Stitch:
__tablename__ = 'stitch'
def __init__(self, params, name):
self.name = name
self.params = params
def create(self, clz, *args, **kwargs):
return clz(self.params, *args, **kwargs)
creator = Creator('params')
stitch1 = Stitch('pp', 'my_name')
print("stitch1= ", stitch1)
for clazz in [Stitch]:
setattr(Creator, 'create_%s' % clazz.__tablename__, functools.partial(stitch1.create, clazz))
stitch = creator.create_stitch('myname')
print("stitch= ", stitch)