Safely bind method from one class to another class in Python
本问题已经有最佳答案,请猛点这里访问。
我知道我可以将一个函数附加到一个类,并使其成为一个方法:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> def is_not_bound(inst, name): ... print("Hello %s" % name) ... >>> >>> class NoMethods: ... pass ... >>> >>> setattr(NoMethods, 'bound', is_not_bound) >>> >>> NoMethods().bound("oz") # prints: Hello oz Hello oz |
令我惊讶的是,这也适用于从一个类到另一个类的绑定方法:
1 2 3 4 5 6 7 8 9 10 11 | >>> class Foo: ... def foo(self, name): ... print("Hello %s" % name) ... >>> class B: ... pass ... >>> setattr(B, 'bound_to_b', getattr(Foo, 'foo')) >>> B().bound_to_b("confused?") Hello confused? >>> |
我能安全使用这个吗?我在监督什么?
更新我已经发现了一个警告:
1 2 | >>> B.bound_to_b <function Foo.foo at 0x7fc997e8b730> |
尽管我从B调用了这个方法,但它似乎与foo绑定在一起。
更令人惊讶的是!:
1 2 3 4 5 6 7 8 | >>> def new_method(self, addto): ... return self.num + addto ... >>> setattr(B, 'add', new_method) >>> b=B() >>> b.num = 2 >>> b.add(2) 4 |
显然,这是一种有意的行为(很酷!)但显然,这种行为并不十分熟悉。
如果您认识Python2很长时间了,您可能不知道Python3没有任何方法(如上所述)。
所以在Python 3中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | >>> class Foo: ... def foo(self, name): ... print("Hello %s" % name) ... >>> Foo.foo <function Foo.foo at 0x7f729a406730> >>> def foo(): ... pass ... >>> foo <function foo at 0x7f729b83ff28> >>> >>> Foo.foo <function Foo.foo at 0x7f729a406730> |
没有区别!但是,在Python2中:
1 2 3 4 5 6 7 8 9 10 | Python 2.7.14 (default, Feb 2 2018, 02:17:12) [GCC 7.3.0] on linux2 Type"help","copyright","credits" or"license" for more information. >>> class Foo: ... def foo(self, name): ... print("Hello %s" % name) ... >>> Foo.foo <unbound method Foo.foo> >>> |