• 0904


    1. 静态方法

    class Animal(object):
        def __init__(self,name):
            self.name = name
            
        @staticmethod     #静态方法的调用方式
        def eat(self,food):
            print('% is eating %s' % (self.name,food))
    d = Animal('zhang')
    d.eat('hanb')
    
    
    #直接按上面写然后执行,会报错:TypeError: eat() missing 1 required positional argument: 'food'。说是缺少一个food参数,可是我们不是传了一个food参数hanb嘛,我们稍后再说,看下面代码。
    
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
            
        @staticmethod
        def eat(food):
            print('%s is eating %s' % ('zhangshanci',food))
    d = Animal('zhang')
    d.eat('hanb')
    
    #不给eat方法传self了,直接传一个food,代码运行结果:zhangshanci is eating hanb
    #这次就没错了,但是类里面的每个方法不是都要传一个self参数嘛,为什么eat不传也不报错呢,接下来看下面的代码,不给eat传任何参数了,
    
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
            
        @staticmethod
        def eat():
            print('%s is eating %s' % ('zhangshanci','hanb'))
    d = Animal('zhang')
    d.eat()
    
    #运行结果是:zhangshanci is eating hanb,也没有报错。
    
    
    #通过上面的例子,我们总结出来,静态方法其实跟类没有半毛钱关系,它只是通过类的实例来调用而已,类的self、类的属性、类的任何任何都不会传给静态方法使用,所以上面的eat(self,food),需要这样用:eat('zhangshanci','chifan'),手动传给它两个参数,因为eat里的self参数并不是类的对象,而是一个普普通通需要传入的参数而已。
    
    
    #那么静态方法如何使用类的属性呢,看如下代码:
    class Animal(object):
        def __init__(self,name):
            self.name = name
            
        @staticmethod
        def eat(self):
            print('%s is eating %s' % (self.name,'hanb'))
    d = Animal('zhang')
    d.eat(d)
    
    #把类的对象传入eat方法作为一个参数,然后再调用。这样其实没啥卵用,实际工作中好像也没有用到的地方,不过要知道这个方法,遇到了能看懂。

    2.类方法

    class Animal(object):
        def __init__(self,name):
            self.name = name
        @classmethod
        def eat(self):
            print('%s is eating %s' % (self.name,'hanb'))
    d = Animal('zhang')
    d.eat()
    
    #上面的代码报错如下:
    #print('%s is eating %s' % (self.name,'hanb'))
    #AttributeError: type object 'Animal' has no attribute 'name'。说是Animal这个类没有name属性,但是构造方法里明明有啊,我们接着看下面的代码。
    
    class Animal(object):
        name = 'zhangshanci'     #加了一个类变量
        def __init__(self,name):
            self.name = name
        @classmethod
        def eat(self):
            print('%s is eating %s' % (self.name,'hanb'))
    d = Animal('zhang')
    d.eat()
    
    #结果如下:
    #zhangshanci is eating hanb
    
    #由此可见,类方法只能调用类变量。实际工作中也几乎用不到,知道有这个就行了。

    3.属性方法

    #我们还是一点点来,通过用多个例子的结果慢慢引入属性方法的特点、使用
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
        @property     #定义属性方法的装饰器
        def eat(self):
            print('%s is eating %s' % (self.name,'hanb'))
    d = Animal('zhang')
    d.eat()
    
    #上面的代码报错:d.eat()
    #TypeError: 'NoneType' object is not callable。说这个eat()方法不能被调用,这是为啥呢,上面的类里都定义了啊,那我们尝试把括号去掉,如下,
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
        @property
        def eat(self):
            print('%s is eating %s' % (self.name,'hanb'))
    d = Animal('zhang')
    d.eat     #调用时去掉了括号
    
    #结果:zhang is eating hanb。可见,属性方法的调用方式是把方法像属性那样调用,属性方法就是把一个方法变成一个属性了,不用加括号直接可调用;
    #那能不能给属性方法传参数呢?就上面的代码来看是不可以的,因为嫁入eat(self,food)这样定义,那调用时这样写d.eat('chirou')和这样写d.eat都会报错缺少一个参数。
    #那怎么解决呢?既然属性方法是把方法变成了一个属性,属性可以赋值,所以我们利用给属性赋值的方法来把参数传进去,看下面代码,
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
        @property
        def eat(self):
            print('%s is eating %s' % (self.name,'baozi'))
    d = Animal('zhang')
    d.eat
    d.eat = 'junzi'
    
    #直接给属性方法赋值是会报错的:    d.eat = 'junzi'
    #AttributeError: can't set attribute,提示不能设置这个属性,需要特殊处理才能赋值,接着往下看,
    
    
    class Animal(object):
        def __init__(self,name):
            self.name = name
        @property    #定义属性方法
        def eat(self):
            print('%s is eating %s' % (self.name,'baozi'))
        @eat.setter    #给属性方法赋值
        def eat(self,food):
            print('eat set food:',food)
    d = Animal('zhang')
    d.eat
    d.eat = 'junzi'
    
    #结果:
    #zhang is eating baozi
    #eat set food: junzi
    #可见,直接调用属性方法,它会执行@property下面的方法;给属性方法赋值,会执行@eat.setter下面的方法;他俩的方法名必须是一样的,这样就起到了给属性方法传参数的效果。(d.eat = 'juanzi' 就好像是 d.eat('jaunzi'))
    
    下面的代码依然是给属性方法传参,更接近实际使用,如下,
    class Animal(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):
            self.__food = food
    d = Animal('zhang')
    d.eat = 'junzi'     #先给属性赋值(也就是变相的传参)
    d.eat    #再调用属性
    
    #结果:
    #zhang is eating junzi  #本来self.__food是None,经过d.eat='juanzi'后,d.eat再执行时self.__food就变成了juanzi。
    
    
    
    接下来的问题是,既然属性方法是一个属性,那怎么删除呢?我们还是直接删除看看,
    class Animal(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):
            self.__food = food
    d = Animal('zhang')
    d.eat
    d.eat = 'junzi'
    d.eat
    del d.eat    #尝试删除这个属性
    #结果报错:del d.eat
    #AttributeError: can't delete attribute,提示不能删除这个属性,跟设置属性值一样,我们需要稍微处理一下,代码如下,
    
    class Animal(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):
            self.__food = food
        @eat.deleter   #删除属性方法的装饰器
        def eat(self):
            del self.__food
            print('delete self.__food')
    d = Animal('zhang')
    d.eat
    d.eat = 'junzi'
    d.eat
    del d.eat     #删除属性d.eat
    d.eat
    
    #结果:
    #zhang is eating None
    #zhang is eating junzi
    #delete self.__food
    #   print('%s is eating %s' % (self.name,self.__food))
    #AttributeError: 'Animal' object has no attribute '_Animal__food',提示Animal这个类对象没有__food变量,这是因为执行del d.eat时调用了eat@deleter下面的方法,方法里有个del self.__food,既然删了自然就找不到了。
    
    #总结:直接调用属性方法,会调用@property下面的方法;给属性方法赋值,会调用@func_name.setter下面的方法;删除属性方法,会调用@func.deleter下面的方法;至于各个方法里写什么就比较灵活了,写什么执行什么。

    好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

    1. 连接航空公司API查询

    2. 对查询结果进行解析 

    3. 返回结果给你的用户

    因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?实例代码如下,

    class Flight(object):
        def __init__(self,name):
            self.flight_name = name
    
    
        def checking_status(self):
            print("checking flight %s status " % self.flight_name)
            return  1
    
    
        @property
        def flight_status(self):
            status = self.checking_status()
            if status == 0 :
                print("flight got canceled...")
            elif status == 1 :
                print("flight is arrived...")
            elif status == 2:
                print("flight has departured already...")
            else:
                print("cannot confirm the flight status...,please check later")
       
        @flight_status.setter #修改
        def flight_status(self,status):
            status_dic = {
                0 : "canceled",
                1 :"arrived",
                2 : "departured"
            }
            print("33[31;1mHas changed the flight status to 33[0m",status_dic.get(status) )
    
        @flight_status.deleter  #删除
        def flight_status(self):
            print("status got removed...")
    
    f = Flight("CA980")
    f.flight_status
    f.flight_status =  2 #触发@flight_status.setter 
    del f.flight_status #触发@flight_status.deleter 

     9.异常处理

    try:
        code
    except error as e:    #捕捉一个异常
        print(e)
    except (error1,error2) as e:    #捕捉多个异常
        print(e)
    except Exception as e:    #捕捉所有异常,建议放在最后,因为它的范围太大,不好定位异常。
        print(e)
  • 相关阅读:
    Linux下管道编程
    【Windows】用信号量实现生产者-消费者模型
    初识【Windows API】--文本去重
    HDU 5183 Negative and Positive (NP) --Hashmap
    【ASC 23】G. ACdream 1429 Rectangular Polygon --DP
    UVALive 4670 Dominating Patterns --AC自动机第一题
    POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
    我也来写2014年总结
    UVALive 4870 Roller Coaster --01背包
    UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?
  • 原文地址:https://www.cnblogs.com/fuckily/p/5843663.html
Copyright © 2020-2023  润新知