如何使用 `functools.partial()` 将方法动态添加到 class
How to dynamically add method to class with `functools.partial()`
在以下情况下,我无法正确使用 functools.partial
将动态方法添加到 class。下面有一个Creator
class,我想在其中添加一个create_someclass
方法,它被creator
class状态部分参数化。
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'
这是为 class 方法制作 partial
的问题,因此在 Python 3.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)
在以下情况下,我无法正确使用 functools.partial
将动态方法添加到 class。下面有一个Creator
class,我想在其中添加一个create_someclass
方法,它被creator
class状态部分参数化。
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'
这是为 class 方法制作 partial
的问题,因此在 Python 3.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)