python 继承

下简单说下我学习python继承的一些想法与经验。

在学习python的面向对象时,我始终参照的是c++的面向对象机制。相对而言,python的面向对象确实更简单一些。

基础:

  1. 整数也被作为对象。前面就看到过,说所有的东西都是对象,包括函数。
  2. 属于一个对象或类的变量被称为域——这个名称有点奇怪,c++叫成员。
  3. 域分为两种,分别属于对象和属于类——其实就是成员和静态成员。
  4. Self指针:相当于c++中的this。
  5. python中,可以把类当成另一种形式的函数,self告诉python使用哪个对象的成员变量。
  6. python中,类成员函数和全局函数相同名都只存在一个。后写的函数会覆盖先前的,不存在函数重载。

__init__方法

  1. 类的构造函数是__init__方法,它在创建类的时候调用。
  2. 它并不是必须的,可以没有。

成员变量和类的变量,方法

  1. 类变量的定义:缩进和方法的缩进相同。引用的时候,需要使用class.变量名的方式。
  2. 成员变量可以在类内的任意地方定义。在成员函数内定义的话,self.xxx=... 就可以了。但在逻辑上要保证使用这个成员变量时,它已经定义。
  3. 在类内,成员函数之外定义的变量是类成员。所有这个类的对象都可以调用。

析构函数

__del__方法相当于他的析构函数,在对象被销毁的时候调用。

私有函数

如果成员函数或成员变量以双下划线__开始,表示private。不以双下划线开始命名的是公胡成员。python中没有类的保护成员。

继承:

继承时成员特性:

  1. 对于类的成员,在子类中可以通过父类.变量名或者子类.变量名来访问,是相同的。
  2. 对于对象的成员,在子类中通过self.变量名来访问。访问不属于这个类的私有成员“_classname__method”或“_classname__variable”

继承时方法的特性:

  1. 生成子类的构造函数的时候,不会自动调用父类的构造函数,你必须手动调用它。同时,在对象释放的时候,同样要手动调用析构函数。
  2. 子类的构造函数和析构函数可以不定义,如果不定义的话,这会调用基类的构造和析构函数。
  3. Python不存在动态绑定和静态绑定。这一点和c++不同。
  4. 如果基类有一个public函数,子类中重新定义一个和他名称相同,子类覆盖父类函数,python中没有函数重载,一个函数名只能对应一个函数。

这种继承模型确实非常简单。

特殊方法:

  1. __init__(self,...)   这个方法在新建对象恰好要被返回使用之前被调用。
  2. __del__(self)    恰好在对象要被删除之前调用。
  3. __str__(self)   在我们对对象使用print语句或是使用str()的时候调用。
  4. __lt__(self,other)    当使用 小于运算符(<)的时候调用。类似地,对于所有的运算符(+,>等等)都有特殊的方法。
  5. __getitem__(self,key)    使用x[key]索引操作符的时候调用。
  6. __len__(self)    对序列对象使用内建的len()函数的时候调用。

下面介绍下我写python类继承遇到的奇葩问题:

一个非常简单的例子:

class A(object):
    def tell(self):
        print 'A tell'
        self.say()
    def say(self):
        print 'A say'
        self.__work()

    def __work(self): # private
        print 'A work'

        
class B(A):
    def tell(self):
        print '\tB tell'
        self.say()
        super(B,self).say()
        A.say(self)
    def say(self):
        print '\tB say'
        self.__work()

    def __work(self): # private
        print '\tB work'
        self.__run()

    def __run(self): # private
        print '\tB run'
        
b = B()
b.tell()

获得的结果:

	B tell
	B say
	B work
	B run
A say
A work
A say
A work

再把例子中的私有函数,全变成public的
class A(object):
    def tell(self):
        print 'A tell'
        self.say()
    def say(self):
        print 'A say'
        self.work()

    def work(self): # public
        print 'A work'

        
class B(A):
    def tell(self):
        print '\tB tell'
        self.say()
        super(B,self).say()
        A.say(self)
    def say(self):
        print '\tB say'
        self.work()

    def work(self): # public
        print '\tB work'
        self.run()

    def run(self): # public
        print '\tB run'
        
b = B()
b.tell()


获得结果:

	B tell
	B say
	B work
	B run
A say
	B work
	B run
A say
	B work
	B run

从这个例子里可以看到,想用python在父类调用子类的override函数,最好把相关函数全变为公有。

python适合做胶水,不适合做零件。涉及到复杂设计及计算效率的代码,还得用C++。

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值