Python中的运行时方法修补

news/2024/7/10 1:36:27 标签: java, python, 设计模式, vue,

Often, when programming, we may want to change some already set behavior. This can be accomplished by sub-classing whatever classes we have and overriding those methods we are not happy with.

通常,在编程时,我们可能想要更改一些已经设置的行为。 这可以通过对我们拥有的所有进行子化并覆盖我们不满意的那些方法来实现。

While this works with our own code, what happens if we want to change third party code? Of course we can edit it so that it instantiates one of our sub-classes, this however, can create another whole set of problems. What we need to do then, is to figure out a way to replace an object’s methods with our own.

尽管这适用于我们自己的代码,但是如果我们想更改第三方代码会怎样? 当然,我们可以对其进行编辑,以使其实例化我们的一个子,但是,这可能会带来另一整套问题。 然后,我们需要做的是找出一种用我们自己的方法替换对象方法的方法。

补习班 (Patching classes)

Probably the easiest way of adding a new method to an object or replacing an existing one is by patching its class. Say we want to teach our Dog class from the previous example how to howl, we can easily do it by defining a new howl function and adding it to our class like so:

向对象添加新方法或替换现有方法的最简单方法可能是修补其。 假设我们想从前面的示例中教我们的Dog如何to叫,我们可以通过定义一个新的howl函数并将其添加到我们的中来轻松地做到这一点,如下所示:

While this is extremely easy to do, there’s a couple of things we should be aware of. First of all, all instances of the modified class will be updated, meaning that not only new objects will have the new method definitions, but that all objects we created before patching our class will have them too (unless they haven’t overridden the method themselves). Second, the new or modified methods will be bound, meaning that the first argument (i.e. ‘self’) will be the object being called.

尽管这非常容易做到,但是我们需要注意几件事。 首先,将修改的所有实例,这意味着不仅新对象将具有新的方法定义,而且在修补之前我们创建的所有对象也将具有它们(除非它们没有重写方法)他们自己)。 其次,将绑定新的或修改的方法,这意味着第一个参数(即“ self”)将成为被调用的对象。

修补对象 (Patching objects)

Individual objects can also be patched without having to affect all other instances of its class. There is, however, a little gotcha when doing it. Lets look at the following example:

也可以修补单个对象,而不必影响其的所有其他实例。 但是,这样做时有一点陷阱。 让我们看下面的例子:

Now, let’s try calling our newly defined method:

现在,让我们尝试调用我们新定义的方法:

border_collie.herd(sheep)

TypeError: herd() takes exactly 2 arguments (1 given)

border_collie.herd(sheep)

TypeError: herd() takes exactly 2 arguments (1 given)

The problem with the previous code is that herd is not a bound method, just take a look at the following code:

先前代码的问题在于, herd不是绑定方法,只需看下面的代码即可:

This means that the object being called is not passed as the first argument to the function, causing the error we previously saw. We can of course pass the instance ourselves, but that wouldn’t work when replacing methods. The correct way of patching an object is by using the MethodType function in the types module like so:

这意味着被调用的对象不会作为第一个参数传递给函数,从而导致我们先前看到的错误。 我们当然可以自己传递实例,但是在替换方法时不起作用。 修补对象的正确方法是使用型模块中的MethodType函数,如下所示:

print border_collie.herd

<bound method ?.herd of <__main__.Dog instance at 0x10427e7e8>>

print border_collie.herd

<bound method ?.herd of <__main__.Dog instance at 0x10427e7e8>>

As we can see the method is now bound and we can safely call it.

如我们所见,该方法现已绑定,可以安全地调用它了。

结论 (Conclusion)

翻译自: https://www.pybloggers.com/2013/07/run-time-method-patching-in-python/


http://www.niftyadmin.cn/n/982379.html

相关文章

【MyBatis学习06】输入映射和输出映射

在前面几篇博文的例子中也可以看到mybatis中输入映射和输出映射的身影&#xff0c;但是没有系统的总结一下&#xff0c;这篇博客主要对这两个东东做一个总结。我们知道mybatis中输入映射和输出映射可以是基本数据类型、hashmap或者pojo的包装类型&#xff0c;这里主要来总结一下…

查看php当前进程数

root用户下执行netstat -napo |grep "php-fpm" | wc -l

UML中关联和依赖的区别收集大全

没关系 > 依赖 > 关联 > 聚合 > 组合。下面是从网上搜集的一些看法&#xff1a; --------- 1. --------- Dependency Relationship Draw a dependency relationship between two classes, or between a class and an interface, to show that the client class de…

python 通过代理请求_Python请求和代理

python 通过代理请求One of Requests’ most popular features is its simple proxying support. HTTP as a protocol has very well-defined semantics for dealing with proxies, and this has lead to widespread deployment of HTTP proxies. Requests最受欢迎的功能之一是…

SSL negotiation failed: Secure connection truncated

svn 更新出现SSL negotiation failed: Secure connection truncated问题&#xff0c;发现是固定ip无法使用&#xff0c;重新指定svn 为拨号的ip。再看svn 的host配置发现是另一台服务中中转的 netstat -anp |grep 8443 发现通过rinetd端口转发 vim /etc/rinetd.conf 在启动服…

在sublime-text中设置浏览器预览

配置在Chrome,Firefox中打开 安装 SideBarEnhancements 然后通过ctrl k, ctrl b打开侧边栏&#xff0c;在侧边栏的文件中右击&#xff0c;找到 open width -> edit applications 然后在这里边设置firefox打开的方式。application : 路径要修改为自己默认安装的路径。[{&qu…

Python装饰器入门

In this tutorial on decorators, we’ll look at what they are and how to create and use them. Decorators provide a simple syntax for calling higher-order functions. 在有关装饰器的本教程中&#xff0c;我们将了解它们是什么以及如何创建和使用它们。 装饰器提供了用…

Redis数据类型(包含新增stream)

1.字符串类型 可以存储任何类型的字符串&#xff0c;包括json字符串&#xff0c;二进制数据&#xff0c;允许最大的容量为512MB 赋值和取值 127.0.0.1:6379> set name ashin OK 127.0.0.1:6379> get name "ashin" 增加指定的整数&#xff08;自动加1&#x…