python面向对象编程

作者: 小船翻不翻 | 来源:发表于2018-06-01 10:40 被阅读0次

    类和实例

    面向过程的编程思路:

    std1 = { 'name': 'Michael', 'score': 98 }
    std2 = { 'name': 'Bob', 'score': 81 }
    
    def print_score(std):
        print('%s: %s' % (std['name'], std['score']))
    

    面向对象编程,简称OOP,是一种程序设计思想。
    使用关键字class 创建一个类对象,对比面向对象的编程思路:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    class Student(object):
        """docstring for Student"""
        def __init__(self, name,sex):
            self.name = name
            self.sex=sex
        
        def print_sex(self):
            print('%s:%s' % (self.name,self.sex))
    

    运行结果:

    image.png

    在一个类中:

    • 类中定义的函数第一个参数永远是self,调用的时候不需要传递;
    • 可通过__init__函数在创建实例的时候,将一些必要的属性绑定到对象中。

    在__init__函数中:

    • 第一个参数永远是self,便是实例对象本身;
    • 有了该函数,在实例化的时候必须传入与之匹配的参数。

    类Student中的 print_sex函数,实现了打印的功能,我们称之为类的封装,在调用时,我们不需要关心它是怎么实现的这个功能

    实例化后的对象,相互之间是独立的。

    • 在类中定义私有变量,就是给变量名添加前缀__ 如:__name
    • 前后都添加__ 的属于特殊变量,可以直接访问
    • 私有变量仍然可以通过_Student__name来访问__name变量
    • 私有变量的数据,可以通过封装函数的方式调用和设置

    约定大于配置,所有变量前面有_的都不要直接访问

    继承和多态

    继承定义了Animal父类,和Dog、Cat两个子类,子类自动继承父类的所有。
    多态在子类中定义父类已有变量,会被直接覆盖,总是调用子类的run()

    class Animal(object):
        def run(self):
            print('Animal is running...')
    
    class Dog(Animal):
        def run(self):
            print('Dog is running...')
        def eat(self):
            print('Eating meat...')
    class Cat(Animal):
        def run(self):
            print('Cat is running...')
    

    在调用过程中,a可以是任意实现了run()函数的对象

    def rungo(a):
        a.run()
    

    获取对象信息

    • type( )
    >>> type(123)==int
    True
    
    • isinstance( )
      可以判断继承关系,优先使用
    isinstance(Dog(), Animal)
    True
    
    • dir( )
      获得一个对象的所有属性和函数
    >>> dir('ABC')
    ['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']
    

    我们可以自定义一个__len__( ) 用于获得类的长度

    >>> class MyDog(object):
    ...     def __len__(self):
    ...         return 100
    ...
    >>> dog = MyDog()
    >>> len(dog)
    100
    #等同
    >>> dog.__len__( )
    

    可以用于反射的getattr()、setattr()以及hasattr()

    from command import MyObject
    
    computer=MyObject()
    def run(x):
        inp = input('method>')
        # 判断是否有这个属性
        if hasattr(computer,inp):
        # 有就获取然后赋值给新的变量
            func = getattr(computer,inp)
            print(func())
        else:
        # 没有我们来set一个
            setattr(computer,inp,lambda x:x+1)
            func = getattr(computer,inp)
            print(func(x))
    
    if __name__ == '__main__':
        run(10)
    

    在使用setattr时,第三个参数传入什么类型,inp对象就会生成什么类型
    在使用getattr时,能使用对象. 出来的,尽量不使用该函数

    实例属性和类属性

    实例属性可以看做动态的
    类属性可以看做是静态的

    优先读取实例属性的值,删除后会自动读取类属性

    >>> class Student(object):
    ...     name = 'Student'
    ...
    >>> s = Student() # 创建实例s
    >>> s.name = 'Michael' # 给实例绑定name属性
    >>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
    Michael
    >>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
    Student
    >>> del s.name # 如果删除实例的name属性
    >>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
    Student
    

    直接类名. 属性 就是一个静态全局的属性

    相关文章

      网友评论

        本文标题:python面向对象编程

        本文链接:https://www.haomeiwen.com/subject/drxqsftx.html