define_method 在 Python
define_method in Python
我想为 Python class 动态定义一些方法。我用谷歌搜索了一会儿,发现 this。我稍微更改了代码以满足我的要求。
这是我的代码:
class Base(object):
def add_method(self, field):
def func(self, value):
self.colors[field] = value
return self
return func
def define_method(self, *fields):
for field in fields:
setattr(self, "with_" + field, self.add_method(field))
class MyColor(Base):
def __init__(self):
self.colors = {
"black": "000",
"red": "f00",
"green": "0f0"
}
# ========== ==========
# by doing this, I assume `with_red()` and `with_green()`
# will be generated, and they're chain-able.
super(MyColor, self).define_method("red", "green")
s = MyColor()
s.with_red("111").with_green("222")
print(s.colors)
# should output: {"black": "000", "red": "111", "green": 222}
代码会引发错误:
Traceback (most recent call last):
File "main.py", line 26, in <module>
s.with_red("111").with_green("222")
TypeError: _with_field() missing 1 required positional argument: 'value'
怎么了?
感谢您的宝贵时间!
==========编辑==========
抱歉,我更改了 Base
class 上的原始实现,如下所示(有一个错误,它总是将最后一个 field
传递给 define_method()
). @Alex 的回答成立。
class Base:
def define_method(self, *fields):
for field in fields:
def _with_field(self, value):
self.colors[field] = value
return self
setattr(self, "with_" + field, _with_field)
发生的事情是你设置了例如'with_red' MyColor 实例上的属性到 Base 构造函数中定义的本地函数 - 请注意,这不是 class 方法,只是一个函数,它接受 2 个参数:'self' 和 'value':
import inspect
...
s = MyColor()
print(inspect.getargspec(s.with_red))
ArgSpec(args=['self', 'value'], varargs=None, 关键字=None, 默认值=None)
一个简单的解决方法是让这个函数接受一个参数:
def _with_field(value):
self.colors[field] = value
return self
通过此更改,您的代码将产生预期的输出。
另一种选择是在 class 上设置 'with_red' 属性 - 这使它成为一种方法,然后隐式传递 self ,你可以保留 _with_field
带有两个参数的签名。
我想为 Python class 动态定义一些方法。我用谷歌搜索了一会儿,发现 this。我稍微更改了代码以满足我的要求。
这是我的代码:
class Base(object):
def add_method(self, field):
def func(self, value):
self.colors[field] = value
return self
return func
def define_method(self, *fields):
for field in fields:
setattr(self, "with_" + field, self.add_method(field))
class MyColor(Base):
def __init__(self):
self.colors = {
"black": "000",
"red": "f00",
"green": "0f0"
}
# ========== ==========
# by doing this, I assume `with_red()` and `with_green()`
# will be generated, and they're chain-able.
super(MyColor, self).define_method("red", "green")
s = MyColor()
s.with_red("111").with_green("222")
print(s.colors)
# should output: {"black": "000", "red": "111", "green": 222}
代码会引发错误:
Traceback (most recent call last):
File "main.py", line 26, in <module>
s.with_red("111").with_green("222")
TypeError: _with_field() missing 1 required positional argument: 'value'
怎么了?
感谢您的宝贵时间!
==========编辑==========
抱歉,我更改了 Base
class 上的原始实现,如下所示(有一个错误,它总是将最后一个 field
传递给 define_method()
). @Alex 的回答成立。
class Base:
def define_method(self, *fields):
for field in fields:
def _with_field(self, value):
self.colors[field] = value
return self
setattr(self, "with_" + field, _with_field)
发生的事情是你设置了例如'with_red' MyColor 实例上的属性到 Base 构造函数中定义的本地函数 - 请注意,这不是 class 方法,只是一个函数,它接受 2 个参数:'self' 和 'value':
import inspect
...
s = MyColor()
print(inspect.getargspec(s.with_red))
ArgSpec(args=['self', 'value'], varargs=None, 关键字=None, 默认值=None)
一个简单的解决方法是让这个函数接受一个参数:
def _with_field(value):
self.colors[field] = value
return self
通过此更改,您的代码将产生预期的输出。
另一种选择是在 class 上设置 'with_red' 属性 - 这使它成为一种方法,然后隐式传递 self ,你可以保留 _with_field
带有两个参数的签名。