zoukankan      html  css  js  c++  java
  • python类相关

    python 绑定到对象的方法

     1 class Foo:
     2     school=0
     3     def __init__(self,name,age,sex):
     4         self.name=name
     5         self.age=age
     6         self.sex=sex
     7         Foo.school+=1
     8     def learn(self):
     9         print('%s is learning' %self.name) #新增self.name
    10 
    11     def eat(self):
    12         print('%s is eating' %self.name)
    13 
    14     def sleep(self):
    15         print('%s is sleeping' %self.name)
    16 
    17 f1=Foo('lit1',18,'Male')
    18 f2=Foo('lit2',19,'Male')
    19 f3=Foo('lit3',20,'FeMale')
    20 
    21 f1.learn()
    22 f2.eat()
    23 f3.sleep()

    类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法,就是带self的那些函数,把自身当做参数传入。

    类本身也是可以调用这些函数的,但必须传入一个实例化的对象,当做self。

    Foo.learn(f1)
    Foo.sleep(f2)
    Foo.eat(f3)
    

    对象之间的交互

     1 class Foo:
     2     def __init__(self,name,salary):
     3         self.name=name
     4         self.salary=salary
     5     def give_money(self,obj,money):
     6         self.salary-=money
     7         obj.salary+=money
     8 
     9 f1=Foo('lit1',4000)
    10 f2=Foo('lit2',1000)
    11 
    12 f1.give_money(f2,100)
    13 
    14 print(f1.salary)
    15 print(f2.salary)

    f1可以给f2money,也可以定义两个不同的类进行,不在举例。

    类的继承和派生

    继承指的是类与类之间的关系,功能之一就是用来解决代码重用问题(比如上一篇文章选课系统中的类,方法基本都是重复的)

    继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

    class ParentClass1: #定义父类
        pass
    
    class ParentClass2: #定义父类
        pass
    
    class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
        pass
    
    class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
        pass

    查看继承的方法,可以根据这个看到父类的查找顺序:

    print(SubClass2.__bases__)

    结果是:

    (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

    以后如果子类调用父类函数,会按照上面的顺序去父类中进行查找。

    属性查找

    class Foo:
        def f1(self):
            print('Foo.f1')
    
        def f2(self):
            print('Foo.f2')
            self.f1()
    
    class Bar(Foo):
        def f1(self):
            print('Bar.f1')
    
    
    b=Bar()
    b.f2()

    结果是:

    Foo.f2
    Bar.f1
    

    会按照类的查找顺序进行查找,别自己想当然,呵呵哒!

    派生

    子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

    class Foo:
        def f1(self):
            print('Foo.f1')
    
        def f2(self):
            print('Foo.f2')
            self.f1()
    
    class Bar(Foo):
        def f1(self):
            Foo.f1(self)
            print('Bar.f1')
    
    
    b=Bar()
    b.f2()

    结果是: 

    Foo.f2
    Foo.f1
    Bar.f1
    

    在子类中,新建的重名的函数属性,在编辑函数内功能的时候,有可能需要重用父类中重名的那个函数功能,应该是用调用普通函数的方式,即:类名.func(),此时就与调用普通函数无异了,因此即便是self参数也要为其传值

    记住,self也要传值。  

    组合

    软件重用的重要方式除了继承之外还有另外一种方式,即:组合

    组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

    class Foo:
        def f1(self):
            print('Foo.f1')
    
        def f2(self):
            print('Foo.f2')
            self.f1()
    
    class Goo:
        def __init__(self):
            self.f=Foo()
    
        def f1(self):
            print('from Goo f1')
    
    g=Goo()
    g.f.f1()  

    结果是:

    Foo.f1
    

    f相当于实例化了一个Foo类的对象,作为Goo的一个变量,也可以调用对应的Foo的函数。  

    子类调用父类的方法

    方法一:指名道姓,即父类名.父类方法()

    #_*_coding:utf-8_*_
    __author__ = 'Linhaifeng'
    
    class Vehicle: #定义交通工具类
         Country='China'
         def __init__(self,name,speed,load,power):
             self.name=name
             self.speed=speed
             self.load=load
             self.power=power
    
         def run(self):
             print('开动啦...')
    
    class Subway(Vehicle): #地铁
        def __init__(self,name,speed,load,power,line):
            Vehicle.__init__(self,name,speed,load,power)
            self.line=line
    
        def run(self):
            print('地铁%s号线欢迎您' %self.line)
            Vehicle.run(self)
    
    line13=Subway('中国地铁','180m/s','1000人/箱','电',13)
    line13.run()
    

      

    super()

    class Vehicle: #定义交通工具类
         Country='China'
         def __init__(self,name,speed,load,power):
             self.name=name
             self.speed=speed
             self.load=load
             self.power=power
    
         def run(self):
             print('开动啦...')
    
    class Subway(Vehicle): #地铁
        def __init__(self,name,speed,load,power,line):
            #super(Subway,self) 就相当于实例本身 在python3中super()等同于super(Subway,self)
            super().__init__(name,speed,load,power)
            self.line=line
    
        def run(self):
            print('地铁%s号线欢迎您' %self.line)
            super(Subway,self).run()
    
    class Mobike(Vehicle):#摩拜单车
        pass
    
    line13=Subway('中国地铁','180m/s','1000人/箱','',13)
    line13.run()

    即使没有直接继承关系,super仍然会按照mro继续往后查找,感觉这样会出问题。。。。

    class A:
        def test(self):
            super().test()
    class B:
        def test(self):
            print('from B')
    class C(A,B):
        pass
    
    c=C()
    c.test() #打印结果:from B
    print(C.mro())

    结果:

    from B
    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
    

    他们的区别

    #指名道姓
    class A:
        def __init__(self):
            print('A的构造方法')
    class B(A):
        def __init__(self):
            print('B的构造方法')
            A.__init__(self)
    
    
    class C(A):
        def __init__(self):
            print('C的构造方法')
            A.__init__(self)
    
    
    class D(B,C):
        def __init__(self):
            print('D的构造方法')
            B.__init__(self)
            C.__init__(self)
    
        pass
    f1=D() #A.__init__被重复调用
    '''
    D的构造方法
    B的构造方法
    A的构造方法
    C的构造方法
    A的构造方法
    '''
    
    
    #使用super()
    class A:
        def __init__(self):
            print('A的构造方法')
    class B(A):
        def __init__(self):
            print('B的构造方法')
            super(B,self).__init__()
    
    
    class C(A):
        def __init__(self):
            print('C的构造方法')
            super(C,self).__init__()
    
    
    class D(B,C):
        def __init__(self):
            print('D的构造方法')
            super(D,self).__init__()
    
    f1=D() #super()会基于mro列表,往后找
    '''
    D的构造方法
    B的构造方法
    C的构造方法
    A的构造方法
    '''
    

      当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

      

     

  • 相关阅读:
    2020软件工程个人作业06————软件工程实践总结作业
    2020软件工程作业01
    班级博客V2.1版本更新日志
    博客园班级手机版
    班级帮助文档
    问题累计
    2020 软件工程作业06
    2020 软件工程作业04
    2020 软件工程作业03
    2020软件工程02
  • 原文地址:https://www.cnblogs.com/litzhiai/p/7978310.html
Copyright © 2011-2022 走看看