Python笔记(五)

5-4 子类和继承
创建类:class subClass(Parent1[Parent1[Parent2,Parent3…]])
子类拥有父类的所有属性,并且可以自己添加自己的属性和方法

注释:父类P:数据max  方法:base() foo()
 class P(object):
     max = 10
     def base():
         print "in parent base"

     def foo():
         print "in parent foo max = %d",max
 注释:子类sub:max 方法:base(),foo()
 class sub(P):
     def foo1():
         print "in sub foo1 max = %d",max

 s = sub()
 s.foo1() 注释:使用的是sub类自己派生的方法
 s.base() 注释:使用的是sub中继承P类的base()方法

5-5 继承属性
class P(object):
“Parent Class”
max = 10
def init(self):
print “P init”
Class C(P):
pass
P.max = 10
print(C.max) 注释:C继承P类,所以C.max = 10
P.max = 100
print(C.max) 注释:当父类修改某个属性,子类也会改变 C.max = 100
可以使用ID命令看到他们的地址是一样的
C.max = 99
print(P.max) 注释:当修改子类的max属性后,子类的max属性覆盖了父类
P.max = 1000 的max属性,所以P.max不会改变,在修改P.max时,
print(C.max) C.max也不会受影响,可以使用ID看看地址变化。

pa = P() 注释:生成实例pa,调用P的init方法,输出 P init
pa.class 注释:pa所属类名:main.P
P.doc 注释:P类文档: Parent Class
P.bases 注释:P类父类:(object)

ch = C() 注释:C类没有init方法,因此继承P类的方法,
实例化过程输出 P init
ch.class 注释: ch的类名:main.C
C.doc 注释:doc是特殊的属性,子类不能继承父类的doc属性
C.bases 注释:C的父类是(main.P),base属性时父类的集合

5-6 重载
重载:相同的方法在不同类中不同的实现
class Person(object):
def init(self,name,age):
self.name = name
self.age = age
def eat(self):
print “Preson eat”

    class Student(Person):
        def __init__(self,name,age,grade)
            self.grade = grade

        def eat(self):
            print "Student eat"
Preson类,定义了人的属性,Student类继承了P类,重载了__init__、eat方法

s1 = Student("zhangsan",10,3)
s1.name = zhangsan
s1.age = 10
s1.grade = 3
s1.eat()为子类的方法

重新修改Student类:
        class Student(Person):
            def __init__(self,name,age,grade):
                Person.__init__(self,name,age)
                self.grade = grade
            def eat():
                print "Student eat"
如何在子类中调用父类的方法?
比如 s1 = Student("zhangsan",10,3)
    s1.eat()如何调用P类的eat()
    在子类的eat方法中添加一句  Persoon.eat(self) 就可以了

直接在子类中使用父类名调用父类的方法弊端:

class A (object):            
    def foo(self):
        print "in A foo"
class B (object):            
    def foo(self):
        print "in B foo"
class C (A):            
    def foo(self):
        A.foo(self)
 C继承A,并且调用了A的foo()的方法,如果C类的父类改为B类
 我们就需要修改C类的代码,如果方法多了那么就显得太麻烦了

 super:直接用类名调用父类:
class A (object):            
    def foo(self):
        print "in A foo"
class B (object):            
    def foo(self):
        print "in B foo"
class C (A):            
    def foo(self):
        super(C,self).foo()

通过super方式可以解决上面问题

多重继承:子类继承多个基类(父类)。多重继承问题:如何在父类中
找到子类中没有或者调用父类的方法。

Python类分为经典类和新式类
经典类是默认没有派生自某个基类:class A:
                                pass
经典类多重继承的时候采用从左到右,深度优先的匹配方法

新式类默认派生object基类:class A(object):
                            pass
新式类采用广度优先匹配法则

经典类是没有__MRO__和instance.mro()调用的,而新式类是有的

分析GR类方法的查找顺序:
class P1(object) :    
    def foo(self):
        print "in A foo"

class P2(object):
    def foo(self):
        pass
    def foo1(self):
        print "in P2 foo1"

class C1(P1, P2) :
    pass

class C2(P1, P2) :
    def foo1(self):
         print "C2 foo1"

class GR(C1,C2):
    pass
gr = GR()
gr.foo()
gr.foo1()

P1和P2的object去掉,经典类查找顺序:
GR.foo()查找过程:GR > C1 > P1
GR.FOO1()查找过程:GR > C1 > P1 > P2

新式类查找顺序:
GR.foo()查找过程:GR > C1 > C2 > P1
GR.foo1()查找过程:GR > C1 > C2
新式类有__mro__属性,可以知道查找顺序。

5-7 组合
组合:当一个类被定义后,就可以当作一个模块来使用,
可以把不同的类混合合并加入到其他类中,来增加功能和代码的重用性。
class Teachers(object):
def init(self,num):
self.num = num

class Students(object):
    def __init__(self,num):
        self.num = num

class School(objecct):
    def __init__(self,name,teachers,students):
        self.name = name
        注释:School自由身和Teachers与Students类组合而成
        self.teachers = teachers 
        selfstudents = students
分别创建Teachers和Students实例,然后创建一个学校实例
sch = School("清华",Teachers(1000),Students(200000))
sch.name
sch.techers.num 注释:访问学校老师数量
sch.students.num 注释:访问学校学生数量

5-8 类内建函数
issubclass(X,b) X是否是B的一个子类
isinstance(object,A) object是否是A的实例
hasattr()/getatter()/
setattr()/delattr() 得到和设置或者实例的属性
dir([object]) 得到类的属性
super() 根绝子类找到父类,类必须是新式类
vars([object]) 返回类属性,没有object返回locals()

类有很多特殊方法:
__strt__:字符输出
运算:__add__,__sub__,__mul__,__div__等
比较:__cmp__
构建自己的类:需求:给定一个浮点数,只保小数点后两位
                  实现加减乘除,支持print.
class F(object):
    def __init__(self,val):
        self.data = round(val,2)

    def __str__(self):
        return str(self.data)

    def __add__(self,other):
        return F(self.data + other.data)
f1 = F(10.202)
f2 = F(2.457)

私有化类属性:使用双下划线(__)开始的属性和方法不能通过类和实例直接访问
class F(object):
    def __init__(self,val):
        self.__data = val 注释:不能直接访问该属性

    def show_data(self):
        print self.__data
f = F(10)
f.__data 注释:访问失败,可以dir看一下类属性
f.show_data() 注释:可以正常访问

包装:对于一个存在的对象进行包装,增加新的,删除不要
    或者对已存在属性进行修改
授权:所有跟新功能有新的类来完成,已经存在的功能
    授权给默认属性,关键实现__getatter__()重载

class W(object):
    def __init__(self,obj):
        self.__data = obj

    def get(self):
        return self.__data

    def __str__():
        return str(self.__data)

    def __getattr__(self,attr):
        return getattr(self.__data,attr)

list1 = W([1,2,3])
list1 [1,2,3]
list1.index(2)[1]
list1.pop()
list1 [1,2]

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Reward
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • © 2015-2020 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信