• python3.x 基础七:面向对象进阶


    类的高级方法:

    1.静态方法:在类方法前增加关键字@staticmethod,将普通方法变成静态方法,不能再次传值,不能访问实例变量或者类变量,与类的关系仅仅是通过类名进行调用

    2.类方法:在类方法前增加关键字@classmethod,类方法只能访问类变量,不能访问实例变量

    3.属性方法:(重点)在类方法前增加关键字@property,调用的时候通过属性一样的方式访问(去掉括号调用),可以通过类私有属性加@setter重新赋值,@deleter删除私有属性后方能删除属性方法

    • 静态方法:
    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    obj1=Dog('hashiqi')
    obj1.eat('baozi')

    正常输出:hashiqi is eating baozi

    增加关键字staticmethod:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @staticmethod
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    obj1=Dog('hashiqi')
    obj1.eat('baozi')

    报错:

    Traceback (most recent call last):
      File "D:/001python/01course/day07/static_method.py", line 11, in <module>
        obj1.eat('baozi')
    TypeError: eat() missing 1 required positional argument: 'food'

    eat的实参没有传给self

    结论:增加关键字@staticmethod后,类的方法变成了单纯的函数,无法访问类或者实例中的任何属性,仅增加类名进行调用

    如果非要给静态方法传类属性,可以直接将对象传进去---没有意义:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @staticmethod
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat(obj1)

    输出:hashiqi is eating 

    • 类方法  --关键字@classmethod

    类方法无法访问实例属性

    class Dog(object):
        #name='yzw'
        def __init__(self,name):
            self.name=name
        @classmethod
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat()

    报错如下:

        print('%s is eating '%(self.name))
    AttributeError: type object 'Dog' has no attribute 'name'

    类方法只能访问类属性:

    class Dog(object):
        name='yzw'
        def __init__(self,name):
            self.name=name
        @classmethod
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat()

    输入:yzw is eating 

    • 属性方法--关键字@property

    无法正常使用调用方法

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat()

    报错如下:

        obj1.eat()
    TypeError: 'NoneType' object is not callable

    改成调用属性的方法,也就是把括号去掉:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat

    正常输出:hashiqi is eating 

    结论:把一个方法变成一个静态属性,无法通过()进行调用,它可以通过"对象.属性"进行调用

    属性普通赋值也会报错:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print('%s is eating '%(self.name))
    obj1=Dog('hashiqi')
    obj1.eat
    obj1.eat='value'
    
    error:
        obj1.eat='value'
    AttributeError: can't set attribute

    结论:属性方法可以通过属性调用方式获取,但是不能直接给予赋值

    通过特殊处理给属性方法传值:

    再写一个同名的方法,使用@xxx.setter关键字进行赋值,但是怎么才能给属性里面的形参传值呢?

    class Dog(object):
        def __init__(self,name):
            self.name=name
        @property
        def eat(self):
            print('%s is eating '%(self.name))
        @eat.setter
        def eat(self,food):
            print(food)
    obj1=Dog('hashiqi')  #正常实例化对象
    obj1.eat  # 调用属性方法
    obj1.eat='value'  #调用属性赋值方法
    
    hashiqi is eating 
    value

    属性传值二:

    通过在构造方法里增加私有属性,给属性方法其他形参传值

    class Dog(object):
        def __init__(self,name):
            self.name=name
            self.__food=None
        @property
        def eat(self):
            print('%s is eating'%self.name,self.__food)
        @eat.setter
        def eat(self,food):
            print(food)
            self.__food=food
    d=Dog('hashiqi') # 1.正常实例化对象
    d.eat   # 2.正常调用属性方法  输出:hashiqi is eating None,此时self.__food的值取构造方法的初始值
    d.eat='包子'  # 3.通过setter属性赋值方法给方法赋值
    d.eat   # 4.再次调用属性方法,输出属性方法的结果,此时属性方法调用setter里设置的值
    
    hashiqi is eating None 
    baozi
    hashiqi is eating baozi 

    删除属性方法--无法删除:

    class Dog(object):
        def __init__(self,name):
            self.name=name
            self.__food=None
        @property
        def eat(self):
            print('%s is eating %s '%(self.name,self.__food))
        @eat.setter
        def eat(self,food):
            print(food)
            self.__food=food
    obj1=Dog('hashiqi')
    obj1.eat
    obj1.eat='baozi'
    obj1.eat
    del obj1.eat
    
    error
    AttributeError: can't delete attribute

    删除属性方法--先删除私有属性

    class Dog(object):
        def __init__(self,name):
            self.name=name
            self.__food=None
        @property
        def eat(self):
            print('%s is eating %s '%(self.name,self.__food))
        @eat.setter
        def eat(self,food):
            print(food)
            self.__food=food
        @eat.deleter
        def eat(self):
            del self.__food
            print('had been deleted')
    obj1=Dog('hashiqi')
    obj1.eat
    obj1.eat='baozi'
    obj1.eat
    del obj1.eat
    
    hashiqi is eating None 
    baozi
    hashiqi is eating baozi 
    had been deleted

    删除再进行调用报错:

    class Dog(object):
        def __init__(self,name):
            self.name=name
            self.__food=None
        @property
        def eat(self):
            print('%s is eating %s '%(self.name,self.__food))
        @eat.setter
        def eat(self,food):
            print(food)
            self.__food=food
        @eat.deleter
        def eat(self):
            del self.__food
            print('had been deleted')
    obj1=Dog('hashiqi')
    obj1.eat
    obj1.eat='baozi'
    obj1.eat
    del obj1.eat
    obj1.eat  # 依然是去调用静态方法,此时私有属性已被删除
    
    error
        print('%s is eating %s '%(self.name,self.__food))
    AttributeError: 'Dog' object has no attribute '_Dog__food'

     属性方法用途:隐藏细节,暴露简单接口给用户

    案例:查询航空班次状态

    1.调用航空公司API查询

    2.对查询结果进行分析

    3.将分析后的结果返回页面,用户不关心过程/方法,只关心状态,也就是属性方法的结果

    class Flight(object):
        def __init__(self,name):
            self.fly_name=name
        def checking_status(self):
            print('checking flight %s status...'%self.fly_name)
            return 3
        @property
        def Flight_status(self):
            status=self.checking_status()
            if status == 0:
                print('flight had got canceled')
            if status == 1:
                print('flight is arrived')
            if status == 2:
                print('flight has departured already...')
            if status == 3:
                print('cannot confirm the flight status ... check later pls')
        @Flight_status.setter
        def Flight_status(self,status):
            status_dict={0:'canceled',1:'arrived',2:"departured"}
            print('status has changed to %s'%status_dict.get(status))
    fly1=Flight('A380')
    fly1.Flight_status
    fly1.Flight_status = 1
    
    output:
    checking flight A380 status...
    cannot confirm the flight status ... check later pls
    status has changed to arrived

     类的特殊成员方法

    1.__doc__ 打印类下面的注释信息

    class Class_name(object):
        '''class description'''
        pass
    print(Class_name.__doc__)
    
    output:class description

    2.__module__ 打印模块的名字    __class__ 打印类的名字

    from fly import Flight
    t=Flight('A380')
    print(t.__module__)
    print(t.__class__)
    
    output:
    status has changed to arrived
    fly
    <class 'fly.Flight'>

    3.__init__  构造方法,实例化类的时候自动创建

    4.__del__ 析构方法,一般不定义,系统会自动执行回收垃圾

    5.__call__ 对象后面加括号,触发执行

    class Dog(object):
        def __init__(self):
            pass
        def __call__(self, *args, **kwargs):
            print(*args,**kwargs)
    d1=Dog()
    d1(1,2,3)
    
    output:
    1 2 3

    6.__dict__ 打印字典形式的类属性方法或者实例属性

    class Dog(object):
        address='earth'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def func1(self, *args, **kwargs):
            print(*args,**kwargs)
    print(Dog.__dict__)  #以字典形式打印类的所有属性和方法
    d1=Dog('hashiqi',19)
    print(d1.__dict__)  #以字典形式打印实例的属性

    7.__str__ 如果一个勒种定义了__str__方法,那么打印对象的时候,默认输出该方法的返回值

    class Dog(object):
        address='earth'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def func1(self, *args, **kwargs):
            print(*args,**kwargs)
        def __str__(self):  # 如果没有定义str方法,将打印对象的内存地址
            return ('return value')
    
    d1=Dog('hashiqi',19)
    print(d1)
    
    output:return value

    8. item字典方法,使用起来像操纵字典,其实是类内置方法

    class Dog(object):
        def __getitem__(self, item):
            print('getitem',item)
        def __setitem__(self, key, value):
            print('setitem',key,value)
        def __delitem__(self, key):
            print('delitem',key)
    d1=Dog()  # 1.实例化对象
    value1=d1['key1'] # 2.调用getitem方法
    d1['key2']='value2'  # 3.调用setitem方法
    del d1['key3']  # 4.调用delitem方法
    
    output:
    getitem key1
    setitem key2 value2
    delitem key3

    类的本质

    反射

    • hasattr(obj,name_str) 判断一个对象里是否有对应的字符串方法
    • getattr(obj,name_str)根据字符串去获取obj对象里对应的方法的内存地址
    • setattr(obj,'y',z) 相当于与obj.y=z
    • delattr
    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self):
            print('%s is eating...'%self.name)
    
    d1=Dog('hashiqi')
    choice =input('input>>').strip()
    
    #判断有没有方法
    print(hasattr(d1,choice)) #判断输入的字符串在内存地址中是否存在
    print(getattr(d1,choice)) #获取内存地址,加括号直接调用
    getattr(d1,choice)()

    一般这么用:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    
    d1=Dog('hashiqi')
    choice =input('input>>').strip()  #输入一个方法,如果方法在类中存在,则未true
    if hasattr(d1,choice):
        func=getattr(d1,choice)  #增加一个变量,有助于传入参数
        func('baozi')  #将参数传给判断成功的方法
    
    output:
    input>>eat
    hashiqi is eating baozi

    动态装进取一个新方法:

    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    def bulk(self):
        print("%s is yelling"%self.name)
    d1=Dog('hashiqi')
    choice =input('input>>').strip()  #输入一个方法,如果方法在类中存在,则未true
    if hasattr(d1,choice):
        func=getattr(d1,choice)  #增加一个变量,有助于传入参数
        func('baozi')  #将参数传给判断成功的方法
    else:
        setattr(d1,choice,bulk)
        d1.talk(d1)  #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数
    
    output:
    input>>talk
    hashiqi is yelling

    动态装进去一个属性

    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    def bulk(self):
        print("%s is yelling"%self.name)
    d1=Dog('hashiqi')
    choice =input('input>>').strip()  #输入一个方法,如果方法在类中存在,则未true
    if hasattr(d1,choice):
        func=getattr(d1,choice)  #增加一个变量,有助于传入参数
        func('baozi')  #将参数传给判断成功的方法,如果输入一个已经存在的属性,则不能加括号调用
    else:
        # setattr(d1,choice,bulk)
        # d1.talk(d1)  #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数
        setattr(d1,choice,2)
        print(getattr(d1,choice))
    
    output:
    input>>asdf
    2

    删除一个属性

    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    def bulk(self):
        print("%s is yelling"%self.name)
    d1=Dog('hashiqi')
    choice =input('input>>').strip()  #输入一个方法,如果方法在类中存在,则未true
    if hasattr(d1,choice):
        delattr(d1,choice)
    else:
        # setattr(d1,choice,bulk)
        # d1.talk(d1)  #相当于调用类里面的talk方法,talk实际上就是类外面的bulk函数
        setattr(d1,choice,2)
        print(getattr(d1,choice))
    
    print(d1.name)

    output:
        print(d1.name)
    AttributeError: 'Dog' object has no attribute 'name'

    再变化

    class Dog(object):
        def __init__(self,name):
            self.name=name
        def eat(self,food):
            print('%s is eating %s'%(self.name,food))
    def bulk(self):
        print("%s is yelling"%self.name)
    d1=Dog('hashiqi')
    choice =input('input>>').strip()  #输入一个方法,如果方法在类中存在,则未true
    if hasattr(d1,choice):
        getattr(d1,choice)
    else:
        setattr(d1,choice,bulk)
        func = getattr(d1,choice) #  这里不管choice输入任何东西,都只调用bulk 就是把字符串choice反射成内存中bulk的地址
        func(d1)

    异常处理

    try:
        可能出错的语句
    except 错误关键字1 as 别名:  别名捕获了错误的详细信息
        处理语句
    except 错误关键子2 as 别名:
        处理语句
    或者
    except (错误关键字1,错误关键字2,。。。) as 别名:
        多个错误无法定位
    except Exception:
        不管什么错误都放到这里,不建议一开始用
    else:
        如果except都没有捕捉到异常
        就在这里处理
    finally:
        不管有没有出现错误,都会执行

     自定义异常

    class CustomException(Exception):
        def __init__(self,msg):
            self.msg=msg
    
    try:
        raise CustomException('error') #这里实例化一个类了
    except CustomException as e:  # e保存的就是msg的值
        print(e)
    
    output:
    error
  • 相关阅读:
    Linux-通过破解Root密码来更改用户密码
    测验1:Python基本语法元素(第一周)
    Visual Studio 2019的安装&编写第一个C程序
    STL-vector之邻接表的建立
    分块-区间求和
    代码阅读方法与实践阅读笔记04
    代码阅读方法与实践阅读笔记03
    代码阅读方法与实践阅读笔记02
    代码阅读方法与实践阅读笔记01
    我们应当怎样做需求分析--阅读笔记
  • 原文地址:https://www.cnblogs.com/jenvid/p/8120354.html
Copyright © 2020-2023  润新知