python 魔术方法中重写==的s方法

页面导航:
→ 正文内容 Python子类调用父类
Python实现子类调用父类的方法
这篇文章主要介绍了Python实现子类调用父类的方法,解决子类覆盖父类初始化方法而出现的不确定问题,可通过调用超类构造方法的未绑定版本或者使用super函数来解决,需要的朋友可以参考下
本文实例讲述了Python实现子类调用父类的方法。分享给大家供大家参考。具体实现方法如下:
python和其他面向对象语言类似,每个类可以拥有一个或者多个父类,它们从父类那里继承了属性和方法。如果一个方法在子类的实例中被调用,或者一个属性在子类的实例中被访问,但是该方法或属性在子类中并不存在,那么就会自动的去其父类中进行查找。
继承父类后,就能调用父类方法和访问父类属性,而要完成整个集成过程,子类是需要调用的构造函数的。
子类不显式调用父类的构造方法,而父类构造函数初始化了一些属性,就会出现问题
如果子类和父类都有构造函数,子类其实是重写了父类的构造函数,如果不显式调用父类构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。
先来看看如下示例:
代码如下:class A:
&&& def __init__(self):
&&&&&&& self.namea="aaa"
&&& def funca(self):
&&&&&&& print "function a : %s"%self.namea
class B(A):
&&& def __init__(self):
&&&&&&& self.nameb="bbb"
&&& def funcb(self):
&&&&&&& print "function b : %s"%self.nameb
print b.nameb
运行结果:
代码如下:bbb
function b : bbb
Traceback (most recent call last):
& File "D:workbenchpythonMyPythonProjectteststudyoverwrite_method.py", line 19, in &module&
&&& print b.funca()
& File "D:workbenchpythonMyPythonProjectteststudyoverwrite_method.py", line 6, in funca
&&& print "function a : %s"%self.namea
AttributeError: B instance has no attribute 'namea'
在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的namea属性的代码,为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化。有两种方法能达到这个目的:调用超类构造方法的未绑定版本,或者使用super函数。
方法一:调用未绑定的超类构造方法
修改代码,多增一行:
代码如下:class A:
&&& def __init__(self):
&&&&&&& self.namea="aaa"
&&& def funca(self):
&&&&&&& print "function a : %s"%self.namea
class B(A):
&&& def __init__(self):
&&&&&&& #这一行解决了问题
&&&&&&& A.__init__(self)
&&&&&&& self.nameb="bbb"
&&& def funcb(self):
&&&&&&& print "function b : %s"%self.nameb
print b.nameb
如上有注释的一行解决了该问题,直接使用父类名称调用其构造函数即可。
这种方法叫做调用父类的未绑定的构造方法。在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类的方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。
通过将当前的实例作为self参数提供给未绑定方法,B类就能使用其父类构造方法的所有实现,从而namea变量被设置。
方法二:使用super函数
修改代码,这次需要增加在原来代码上增加2行:
代码如下:#父类需要继承object对象
class A(object):
&&& def __init__(self):
&&&&&&& self.namea="aaa"
&&& def funca(self):
&&&&&&& print "function a : %s"%self.namea
class B(A):
&&& def __init__(self):
&&&&&&& #这一行解决问题
&&&&&&& super(B,self).__init__()
&&&&&&& self.nameb="bbb"
&&& def funcb(self):
&&&&&&& print "function b : %s"%self.nameb
print b.nameb
如上有注释的为新增的代码,其中第一句让类A继承自object类,这样才能使用super函数,因为这是python的“新式类”支持的特性。当前的雷和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。
super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类。
方法一更直观,方法二可以一次初始化所有超类
super函数比在超累中直接调用未绑定方法更直观,但是其最大的有点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.__init__(self)更直观一些。
希望本文所述对大家的Python程序设计有所帮助。
您可能感兴趣的文章:
上一篇:下一篇:
最 近 更 新
热 点 排 行
12345678910从一个Python列表继承后重写append方法
我想创建一个列表,只能接受特定类型。因此,我试图从Python中的列表继承,并重写append()方法,如下所示:
class TypedList(list):
def __init__(self, type):
self.type = type
def append(item)
if not isinstance(item, type):
raise TypeError, 'item is not of type %s' % type
self.append(item) #append the item to itself (the list)
一个无限循环这将追加的主体()调用自己,但我不知道该怎么做其他self.append(项目)。
我应该如何去这样做?
本文地址 :CodeGo.net/186483/
-------------------------------------------------------------------------------------------------------------------------
1. 我已经更改了你的类。这似乎是工作。
一对夫妇的建议:不要'type作为关键字-type是一个内置的函数。 Python实例变量是self.前缀。self.&variable name&。
class TypedList(list):
def __init__(self, type):
self.type = type
def append(self, item):
if not isinstance(item, self.type):
raise TypeError, 'item is not of type %s' % self.type
super(TypedList, self).append(item) #append the item to itself (the list)
from types import *
tl = TypedList(StringType)
tl.append('abc')
tl.append(None)
Traceback (most recent call last):
File "&pyshell#25&", line 1, in &module&
tl.append(None)
File "&pyshell#22&", line 7, in append
raise TypeError, 'item is not of type %s' % self.type
TypeError: item is not of type &type 'str'&
我想创建一个列表,只能
接受某些类型的。因此,我
试图从在一个列表中继承
不是最好的方法! Python的列表有这么多,你不得不被重写一堆(并可能会忘记
相反,包装清单,从继承collections.MutableSequence,并在其上很少有“瓶颈”的方法增加您的支票MutableSequence依赖于所有其他人。
import collections
class TypedList(collections.MutableSequence):
def __init__(self, oktypes, *args):
self.oktypes = oktypes
self.list = list()
self.extend(list(args))
def check(self, v):
if not isinstance(v, self.oktypes):
raise TypeError, v
def __len__(self): return len(self.list)
def __getitem__(self, i): return self.list[i]
def __delitem__(self, i): del self.list[i]
def __setitem__(self, i, v):
self.check(v)
self.list[i] = v
def insert(self, i, v):
self.check(v)
self.list.insert(i, v)
def __str__(self):
return str(self.list)
该oktypes通常 CodeGo.net,你要允许类型的元组,但它的确定通过一个单一类型的存在(当然,并通过制作一种类型的抽象基类,农行,您可以轻松地执行任何类型的类型检查的你选择这种方式-但是,这是一个不同的问题)。
这里的例子这个类:
x = TypedList((str, unicode), 'foo', 'bar')
x.append('zap')
x.append(23)
['foo', 'bar', 'zap']
Traceback (most recent call last):
File "tl.py", line 35, in &module&
x.append(23)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_abcoll.py", line 556, in append
self.insert(len(self), value)
File "tl.py", line 25, in insert
self.check(v)
File "tl.py", line 12, in check
raise TypeError, v
TypeError: 23
请特别注意,我们并没有被重写append-但追加是存在的,只是表现如预期。
背后的mojo,有点不那么秘密的透露,在回溯:_abcoll.py(该模块的抽象基类collections模块),在556行,通过调用我们的追加insert-我们有,当然,适当的覆盖。
这种“设计模式”(绝对于各种面向对象的-找我谈关于设计模式在YouTube上,你会更早找出原因;-),除其他优势,“瓶颈效应”:通过在添加检查一个非常,你必须你获得的好处,那些检查适用于所有_在Python中其他(和可变序列有很多那些;-)。
这并不奇怪,我们最终有一个非常强大的和经典的设计模式“幕后”,这一战略背后的整体思路右出不朽经典“设计模式”一书(其作者经常统称为的团伙四个“;-):喜欢在继承财产继承(从具体类)是一个非常strict的全面的”陷阱“,只要你想它超出了其极限,甚至只是略微做任何事情,组成灵活,继承从适当的非常漂亮的抽象类的图片。
斯科特迈尔斯“优秀”有效的C ++“,第33项,把它更加强烈:让非叶类抽象。既然是“非叶子”这是以往任何时候都继承自“任何类别”,等同措辞是“永远继承自一个具体的类”。
斯科特是写在C ++方面的,当然,但保罗Haahr给出确切的建议对Java,表述为不继承具体类-和我一般第二它为Python,虽然我做青睐的团伙四的更软措辞,更喜欢在组成(具体类)继承(但据我所知,无论斯科特和保罗经常写为观众,需要非常直接和强烈的措辞的建议,几乎表述为“,而不是咨询,不柔和的措辞一个他们可能太容易忽略在他们方便的;-)。
而不是self.append(item)使用super(TypedList, self).append(item)(见
如果不这样做摆在首位。
如果你没有在你的列表中想X型的,你为什么把它呢?
这不是一个讽刺的回应。添加类型限制为你想要么是不必要的或肯定适得其反。它然而,从一种语言背景,具有类型检查要求。
对于你会不会尝试的原因'a string' / 2.0,你有过什么被放在一个列表控制。由于清单会很乐意包含类型,充其量TypedList将移动运行类型错误的地步,向前到您追加到列表中的项目。鉴于Python的鸭打字显式检查isinstance排除列表的后面inflate以包含非type同时提供没有好处的实例。
每在假设的Python 2.7或更高collections.OrderedDict请求将做到这一点。每页该页面中,render2.4或更高版本,你必须添加一个。
本文标题 :从一个Python列表继承后重写append方法
本文地址 :CodeGo.net/186483/
Copyright (C) 2014 CodeGo.net 沪ICP备号 联系电邮: (#=@)温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
操作符重载使我们的对象与内置的一样。__X__的名字的方法是特殊的挂钩(hook),python通过这种特殊的命名来拦截操作符,以实现重载。 python在计算操作符时会自动调用这样的方法,例如:如果对象继承了__add__方法,当它出现在+表达式中时会调用这个方法。通过重载,用户定义的对象就像内置的一样。在类中重载操作符1、操作符重载使得类能拦截标准的python操作。2、类可以重载所有的python的表达式操作符。3、类可以重载对象操作:print,函数调用,限定等。4、重载使得类的实例看起来更像内置的。5、重载是通过特殊命名的类方法来实现的。方法名 &&&&&&&重载的操作说明 &&&&&&&调用表达式__init__ &&&构造函数 &&&&&&&创建对象:class()__del__ &&&&&&&析构函数 &&&&&&&释放对象的时候__add__ &&&&&&&“+” &&&&&&&&&&&x + y__or__ &&&&&&&“|” &&&&&&&&&&&x | y__repr__ &&&打印,转换 &&&&&&&print x, `x`__call__ &&&函数调用 &&&&&&&X()__getattr__ &&&属性引用 &&&&&&&x.undefined__getitem__ &&&索引 &&&&&&&&&&&x[key],for循环,in测试__setitem__ &&&索引赋值 &&&&&&&x[key] = value__getslice__ &&&分片 &&&&&&&&&&&x[low:high]__len__ &&&&&&&长度 &&&&&&&&&&&len(x)__cmp__ &&&&&&&比较 &&&&&&&&&&&x == Y ,x & y__radd__ &&&右边的操作符"+" &&&&&&&非实例 + x例子:__getitem__拦截了所有的索引操作&&& class indexer:def __getitem__(self,index):return index ** 2&&& x = indexer()&&& for i in range(5):print x[i] &&&#x[i]将调用__getitem__(x,i)014916
阅读(817)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'Python中类的操作符重载',
blogAbstract:'Python把操作符和类的内置方法关联起来了,每个操作符对应一个函数。如__add__()表示操作符“+”,__gt__表示操作符“&”。——————————————————————————————————————————————'
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
class P(object):&& &def __init__(self):&& & & &print "calling P's constructor"class C(P):&& &def __init__(self):&& & & &print "calling C's constructor"&&& c=C()calling C's constructor&& & 如果你还想去调用基类的__init__()方法,你需要明确指出使用一个子类的实例去调用基类(未绑定)方法。相应的更新C,会出现下面预期的执行结果。class C(P):&& &def __init__(self):&& & & &P.__init__(self)&& & & &print "calling C's constructor"&&& c=C()calling P's constructorcalling C's constructor&& & python中使用基类名来调用类方法,对应在java中,使用关键之super来实现的,因此,为了方便,python中也引入了内建函数super(),依照下面就可以依葫芦画瓢了:class C(P):&& &def __init__(self):&& & & &super(C,self).__init__()&& & & &print "calling C's constructor"&& & &使用super的漂亮之处在于你不需要明确给出任何基类名字,跑腿的事它就帮你干了!使用suoer()的重点,是你不需要明确提供父类。这意味着你如果改变了类的继承关系,你只需要改变一行代码(class语句本身)而不必再大量代码中去查找所有被修改的那个类的名字。
阅读(1335)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'python:重写__init__不会调用基类的__init__',
blogAbstract:'&& & & & 当从一个带构造器__init__的类派生,如果你不去覆盖__init__,它将会被继承并自动调用。但是如果你在子类中覆盖了__init__,子类被实例化时,基类的__init__将不会被调用。这可能会让了解java的朋友感到吃惊。&&&class P(object):&& &def __init__(self):&& & & &print \"calling P\'s constructor\"class C(P):&& &def __init__(self):',
blogTag:'python,类,继承,super,基类',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:1,
publishTime:6,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 python list 方法 的文章

 

随机推荐