【问题标题】:Metaprogramming in Python - adding an object methodPython 中的元编程 - 添加对象方法
【发布时间】:2014-05-18 03:05:35
【问题描述】:

我有 Python 的背景(虽然完全是自学的,所以我可能有一些坏习惯或误解),我正在尝试学习 Ruby 以扩大我的范围。

我正在阅读一些比较,并看到很多断言“Python 不能进行元编程”(或者,不那么煽情,“Python 不能像 Ruby 一样简单地进行元编程”)。所以我离开并快速阅读了元编程,并得出这样的印象,基本上是在运行时编辑类/对象的方法/行为(如果我不正确,请纠正我!)。

我的印象是,由于 Python 是动态的,所以这应该不是问题。但是,我运行了以下测试代码,但没有给出我预期的响应:

>>> class foo:
...     def make_hello_method(self):
...             def hello(obj):
...                     print 'hello'
...             self.hello = hello
...
>>> f = foo()
>>> f.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: foo instance has no attribute 'hello'
>>> f.make_hello_method()
>>> f.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello() takes exactly 1 argument (0 given)

我的印象是对象的每个方法都会自动将对象本身作为第一个参数传递(因此需要将对象方法定义为(self, [...]))。为什么f 没有被传递给hello()

【问题讨论】:

标签: python metaprogramming


【解决方案1】:

您需要将其设为实例方法。 types 模块中有一个类可以做到这一点。这将起作用:

self.hello = types.MethodType(hello, self)

【讨论】:

  • 啊,明白了。在 f.make_hello_methodf.hello 上调用 type() 可以清楚地看出区别。谢谢!
  • @scubbo:如果您想将方法添加到类中,而不仅仅是一个实例,则需要改用 setattr(foo, "hello", hello) 之类的东西,这会将其添加到类中,所有现有的实例,以及创建的任何新实例。
【解决方案2】:

鉴于您使用的是 Python 2,您可以使用 new 模块来完成这项工作:

self.hello = new.instancemethod(hello, self, foo)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2018-12-06
    • 1970-01-01
    • 2010-11-30
    • 2013-09-23
    • 2014-03-12
    相关资源
    最近更新 更多