在Python中向已加载的类/模块添加方法
如果我有这样的东西:
import mynewclass
我可以给我的新类添加一些方法吗?概念上可以像下面这样:
def newmethod(self,x):
return x + self.y
mynewclass.newmethod = newmethod
(我正在使用 CPython 2.6)
2 个回答
6
是的,如果是Python的类型。不过你应该在类上操作,而不是在模块或包上。
43
在Python中,导入语句是用来引入模块的,而不是类。所以如果你想导入一个类,你需要像这样做:
from mymodule import MyClass
更直接地说,答案是肯定的。在Python中,类其实就是普通的对象,而类的方法就是存储在对象属性中的一个函数。
而且,Python中的对象实例的属性是动态的(你可以在运行时添加新的对象属性),这一点结合前面的内容,意味着你可以在运行时给一个类添加新的方法。
# define a class with just one attribute
class MyClass:
def __init__(self, x):
self.x = x
# creates an instance of the class
obj = MyClass(42)
# now add a method to the class
def new_method(self):
print("x attribute is", self.x)
MyClass.new_method = new_method
# the method can be called even on already existing instances
obj.new_method()
这怎么实现的呢?当你输入:
obj.new_method()
Python会执行以下操作:
首先,它会在对象
obj
中查找new_method
。如果没有找到这个实例属性,它会尝试在类对象中查找(可以通过
obj.__class__
访问),在那里它会找到这个函数。这里有点小技巧,因为Python会注意到它找到的是一个函数,所以会把它“包装”成一个闭包,创建一个叫做“绑定方法”的东西。这是必要的,因为当你调用
obj.new_method()
时,你实际上是想调用MyClass.new_method(obj)
... 换句话说,把这个函数绑定到obj
上,创建绑定方法的过程就是为了处理self
参数。这个绑定方法就是
obj.new_method
返回的内容,然后因为那行代码最后有个()
,所以这个方法会被最终调用。
如果在类中也找不到,Python还会按照特定的顺序搜索父类,以寻找继承的方法和属性,因此事情会变得稍微复杂一些。