Python是否有像C#这样的扩展方法?是否可以调用如下方法:
MyRandomMethod()
现有类型如int
?
myInt.MyRandomMethod()
答案 0 :(得分:50)
您可以在Python代码(AKA Monkey补丁)中定义的类对象上添加您喜欢的任何方法:
>>> class A(object):
>>> pass
>>> def stuff(self):
>>> print self
>>> A.test = stuff
>>> A().test()
这对内置类型不起作用,因为它们的__dict__
不可写(它是dictproxy
)。
所以不,Python中没有“真正的”扩展方法机制。
答案 1 :(得分:9)
不确定你问的是什么,但你可以扩展现有类型,然后在新事物上调用你喜欢的任何东西:
class int(int):
def random_method(self):
return 4 # guaranteed to be random
v = int(5) # you'll have to instantiate all you variables like this
v.random_method()
class int(int):
def xkcd(self):
import antigravity
print(42)
>>>v.xkcd()
Traceback (most recent call last):
File "<pyshell#81>", line 1, in <module>
v.xkcd()
AttributeError: 'int' object has no attribute 'xkcd'
c = int(1)
>>> c.random_method()
4
>>> c.xkcd()
42
希望澄清你的问题
答案 2 :(得分:4)
可以使用禁果(https://pypi.python.org/pypi/forbiddenfruit)
来完成安装forbiddenfruit:
pip install forbiddenfruit
然后你可以扩展内置类型:
>>> from forbiddenfruit import curse
>>> def percent(self, delta):
... return self * (1 + delta / 100)
>>> curse(float, 'percent', percent)
>>> 1.0.percent(5)
1.05
Forbidden Fruit从根本上依赖于C API,它只适用于cpython实现,不适用于其他python实现,如Jython,pypy等。
答案 3 :(得分:1)
答案 4 :(得分:0)
另一种选择是覆盖元类。这使您可以指定所有类中应存在的函数。
本文开始讨论它:
http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html
答案 5 :(得分:0)
以下context manager添加了“禁果”之类的方法,没有任何限制。除此之外,它还有一个额外的好处,那就是在以后删除扩展方法:
class extension_method:
def __init__(self, obj, method):
method_name = method.__name__
setattr(obj, method_name, method)
self.obj = obj
self.method_name = method_name
def __enter__(self):
return self.obj
def __exit__(self, type, value, traceback):
# remove this if you want to keep the extension method after context exit
delattr(self.obj, self.method_name)
用法如下:
class C:
pass
def get_class_name(self):
return self.__class__.__name__
with extension_method(C, get_class_name):
assert hasattr(C, 'get_class_name') # the method is added to C
c = C()
print(c.get_class_name()) # prints 'C'
assert not hasattr(C, 'get_class_name') # the method is gone from C