技术标签: python
转载:http://python.jobbole.com/82357/
相信很多朋友在编程的时候都会想修改一下已经写好的程序行为代码,而最常见的方式就是通过子类来重写父类的一些不满足需求的方法。比如说下面这个例子。
1
2
3
4
5
6
7
|
class
Dog
:
def
bark
(
self
)
:
print
'Woof!'
class
Husky
(
Dog
)
:
def
bark
(
self
)
print
'Howl!'
|
我们可以用上述方式来修改我们自己写的代码,但是我们应该怎么修改第三方代码呢?当然,我们也可以自己编写一个子类,调用子类的实例对象来实现修改,但是这样可能会引入其他一系列问题。所以我们得想个办法用我们自己的方法替换掉原来的对象方法,这就是本文接下来要介绍的“打补丁”的方式。
如果我们想新增或是修改对象的方法的话,最简单的方式莫过于给类打个补丁了。结合上面的例子,如果我们想给我们自己的 Dog
类写一个新的 howl
方法的话,我们可以定义一个新的 howl
函数,像下面的代码一样把它添加到我们的类中:
1
2
3
4
5
6
7
8
9
10
11
|
def
newbark
(
self
)
:
print
'Wrooof!'
def
howl
(
self
)
:
print
'Howl!'
# Replace an existing method
Dog
.
bark
=
newbark
# Add a new method
Dog
.
howl
=
howl
|
很简单吧?但是这里有几个问题需要我们注意。首先,被修改的类的所有实例中的方法都会被更新,所以更新后的方法不仅仅存在于新创建的对象中,之前创建的所有对象都会拥有更新之后的方法,除非只是新增而不是覆盖掉原来的方法。第二,你修改或者新增的方法应当是与对象绑定的,所以方法的第一个参数应当是被调用的对象(在这里就是类的实例self
)。
单个对象也可以在不影响这个类的其他实例的情况下打补丁。但是还是有点小技巧的哦!先让我们看看下面这个例子。
1
2
3
4
5
6
7
|
def
herd
(
self
,
sheep
)
:
self
.
run
(
)
self
.
bark
(
)
self
.
run
(
)
border_collie
=
Dog
(
)
border_collie
.
herd
=
herd
|
然后我们再试试调用新定义的方法:
1
2
3
4
5
6
7
8
|
border_collie
.
herd
(
sheep
)
TypeError
:
herd
(
)
takes
exactly
2
arguments
(
1
given
)
The
problem
with
the
previous
code
is
that
the
herd
is
not
a
bound
method
,
just
take
a
look
at
the
following
code
:
print
border_collie
.
herd
<
function
herd
at
0xf9c5f0
>
|
出错啦!引发错误的原因就是被调用的对象并没有作为第一个参数传给我们写的函数。当然我们可以自己把参数传进去,但是在这个替换类方法的场景下并不奏效。解决这个问题的正确方案是用 type
这个模块里的 MethodType
函数,我们可以看看下面的示例代码:
1
2
3
4
5
6
7
8
9
|
import
types
border_collie
=
Dog
(
)
border_collie
.
herd
=
types
.
MethodType
(
herd
,
border_collie
)
print
border_collie
.
herd
<
bound
method
?
.
herd
of
<
__main__
.
Dog
instance
at
0x23c9518
>>
border_collie
.
herd
(
sheep
)
|
现在我们的方法已经和实例绑定了,大功告成!
运行中替换或者添加方法是非常有用的,比如说在单元测试中,有些负责和外界服务通信的函数就需要替换掉,方便测试。这个技巧不仅很常用,而且在你最终决定要修改代码之前还可以保持代码的可维护性,是一个非常重要的技巧。
CASE p.sharesNature WHEN 0 THEN '限售' WHEN 1 THEN '流通' ELSE '未知' END转载于:https://www.cnblogs.com/xushirong/p/8471406.ht...
GridView控件的属性属性描述AllowPaging指示该控件是否支持分页。AllowSorting指示该控件是否支持排序。AutoGenerateColumns指示是否自动地为数据源中的每个字段创建列。默认为true。AutoGenerat...
文章目录TLM 通信机制组件接口传统的通信手段uvm 组件之间的通信uvm 1.0Push/put modePull/get modeFIFO modeanalysis portPort pass-throughTLM 2.0常用负载组件同步uvm poolTLM 通信机制组件接口sequence <-> drivermonitor -> collectors(scoreboard,coverage)sequence <->matster传统的通信手段缺
在Android源代码中自定义fingerprint特征,由于AOSP的fingerprint特征会被某些应用检测为不安全的系统环境,所以需要修改fingerprint值模拟正常的环境
最近把西门子SCL编程语言从头到尾学了一遍,发现SCL作为PLC中的高级语言,比T型图和语句表使用起来方便多了,特别适合复杂的算法。使用SCL语言编程,小盒子已经完成有关工艺文件的加载和执行、模拟量采集(含滤波及各种报警输出)、以及模拟量输出(多重背景)、以及一些复杂度不是很高的算法(包括:使用平衡法等),对我来说,使用SCL比使用T型图编程效率要高。呵呵……原因有可能是因为本人有C语言的功底+V...
1.信息增益 决策树应该是比较简单的概念了,其结构类似于二叉树,从根节点向下依次判断,直至叶子节点获得结果。对于基本结构不多说了,这里主要说一下和决策树相关的两个数学上的概念,即信息增益和香农熵。信息增益是指的以某一个特征对数据集划分前后数据集发生的变化,而香农熵则是度量这一变化的量。 香农熵的计算公式如下: 计算香农熵的代码:def calcShannonEnt(dataSet
grep过滤查找,管道符:"|",表示将前一个命令的处理结果输出传递给后面的命令处理-n 显示行号,-i忽略大小写查找hello.txt中的yescat hello.tex | grep yes显示行号cat hello.tex | grep -n yes显示行号并且忽略daxiaoxiecat hello.txt | grep -ni yes...
01关于代码安全审计 代码安全审计是查找代码中安全漏洞的方法。在"安全左移"的发展趋势下,代码审计逐渐成为确保代码质量的一个关键环节。代码安全审计通常可以分为: 自动化审计和人工审计。 自动化代码安全审计是以自动化工具的方式查找代码的安全漏洞,这样的工具一般称为静态代码检测工具(SAST)。SAST的一大优势是能够极大地减少查找代码漏洞的时间。静态代码分析流程然而,这类工具往往最让人印象深刻的首先就是“误报率”,据统计,SAST类的产品在OWASP基准测试中最高检出率...
参数使用说明 --name etcd0本member的名字 --initial-advertise-peer-urls http://192.168.2.55:2380其他member使用,其他member通过该地址与本member交互信息。一定要保证从其他member能可访问该地址。静态配置方式下,该
声卡驱动安装出现错误?发布时间:2007-12-03 08:49:07来源:红联作者:jerrya之前一打开什么音频视频,Amarok啊,Xine啊,Kaffeine啊就跟我玩崩溃昨晚上按照一个帖子里所教,去下了realtek-linux-audiopack-4.06a.tar.bz2回来安装驱动本来是想按帖子里手动安装的,但看了Readme后发现可以运行它的一个Install自动安装,于是照做终...
keras-bert是Keras框架加载BERT模型的Python第三方模块,在之前的文章中,笔者介绍了如何使用keras-bret来实现不同的NLP任务,比如:NLP(三十四)使用keras-bert实现序列标注任务NLP(三十五)使用keras-bert实现文本多分类任务NLP(三十六)使用keras-bert实现文本多标签分类任务NLP(三十七)使用keras-bert实现英语序列标注任务NLP(三十九)使用keras-bert实现完形填空及简单的文本纠错功能NLP(四十二)人物关系