Python 中的扩展方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/514068/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:16:43  来源:igfitidea点击:

Extension methods in Python

pythonfunctionextension-methods

提问by Joan Venge

Does Python have extension methods like C#? Is it possible to call a method like:

Python 有没有像 C# 这样的扩展方法?是否可以调用如下方法:

MyRandomMethod()

on existing types like int?

在现有类型上,例如int

myInt.MyRandomMethod()

回答by Torsten Marek

You can add whatever methods you like on class objects defined in Python code (AKA monkey patching):

您可以在 Python 代码中定义的类对象上添加您喜欢的任何方法(又名猴子补丁):

>>> class A(object):
>>>     pass


>>> def stuff(self):
>>>     print self

>>> A.test = stuff
>>> A().test()

This does not work on builtin types, because their __dict__is not writable (it's a dictproxy).

这不适用于内置类型,因为它们__dict__不可写(它是dictproxy)。

So no, there is no "real" extension method mechanism in Python.

所以不,Python 中没有“真正的”扩展方法机制。

回答by SilentGhost

not sure if that what you're asking but you can extend existing types and then call whatever you like on the new thing:

不确定这是否是您要问的,但您可以扩展现有类型,然后在新事物上调用您喜欢的任何内容:

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

hope that clarifies your question

希望能澄清你的问题

回答by Rustam Ganeyev

It can be done with Forbidden Fruit (https://pypi.python.org/pypi/forbiddenfruit)

可以用 Forbidden Fruit ( https://pypi.python.org/pypi/forbiddenfruit)来完成

Install forbiddenfruit:

安装禁果:

pip install forbiddenfruit

Then you can extend built-in types:

然后你可以扩展内置类型:

>>> 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 is fundamentally dependent on the C API, it works only on cpython implementations and won't work on other python implementations, such as Jython, pypy, etc.

Forbidden Fruit 从根本上依赖于 C API,它仅适用于 cpython 实现,不适用于其他 Python 实现,例如 Jython、pypy 等。

回答by hernan43

I've had great luck with the method described here:

我在这里描述的方法很幸运:

http://mail.python.org/pipermail/python-dev/2008-January/076194.html

http://mail.python.org/pipermail/python-dev/2008-January/076194.html

I have no idea if it works on builtins though.

我不知道它是否适用于内置函数。

回答by mrts

The following context manageradds the method like Forbidden Fruit would without the limitations of it. Besides that it has the additional benefit of removing the extension method afterwards:

下面的上下文管理器添加了类似 Forbidden Fruit 的方法,没有它的限制。除此之外,它还有一个额外的好处,那就是在之后删除扩展方法:

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)

Usage is as follows:

用法如下:

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

回答by tsellon

Another option is to override the meta-class. This allows you to, among other things, specify functions that should exist in all classes.

另一种选择是覆盖元类。这允许您指定应存在于所有类中的函数等。

This article starts to discuss it:

本文开始讨论:

http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html

http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html