• 静态方法、类方法、属性方法


    一、静态方法

     1.1、定义

       在类中的方法前面通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Person(object):
     
        def __init__(self, name):
            self.name = name
     
        @staticmethod
        def speak():
            print('someone is speaking chinese.')
     
    # 静态方法在类中也不需要传入 self参数

    1.2、静态方法的特性

      静态方法是不能访问实例变量和类变量的 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Person(object):
     
        def __init__(self, name):
            self.name = name
     
        @staticmethod
        def speak(self):
            print('%s is speaking chinese.' % self.name)
     
    = Person('Bigberg')
    p.speak()
     
     
    # 我们在 speak(self) 函数中传入 self

      事实上以上代码运行会出错的,说speak 需要一个self参数,但调用时却没有传递,没错,当speak变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。  

    1
    2
    3
    4
    Traceback (most recent call last):
      File "G:/python/untitled/study6/静态方法.py", line 26in <module>
        p.speak()
    TypeError: speak() missing 1 required positional argument: 'self'

      想让以上代码可以正常执行,有两种方法:

    1. 在调用时将实例本身传给 speak() 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Person(object):
     
        def __init__(self, name):
            self.name = name
     
        @staticmethod
        def speak(self):
            print('%s is speaking chinese.' % self.name)
     
    = Person('Bigberg')
    p.speak(p)
     
    # 输出
     
    Bigberg is speaking chinese.

      2.在方法speak中去掉self,但这也意味着,在eat中不能通过self.调用实例中的其它变量了 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class Person(object):
     
        def __init__(self, name):
            self.name = name
     
        @staticmethod
        def speak():                # 方法中已经没有 self 参数了
            print('%s is speaking chinese.' % 'anyone')
     
    = Person('Bigberg')
    p.speak()
     
     
    #输出
    anyone is speaking chinese.

    1.3 总结

      普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

    二、类方法

      2.1、定义

      类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

      2.2、访问实例变量

            直接访问实例变量会报错,没有该属性  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class Person(object):
     
        def __init__(self, name, country):
            self.name = name
            self.country = country
     
        @classmethod
        def nationality(self):
            print('Bigberg is %s.' % self.country)
     
    = Person('Bigberg''CN')
    p.nationality()
     
    # 输出
    Traceback (most recent call last):
      File "G:/python/untitled/study6/静态方法.py", line 31in <module>
        p.nationality()
      File "G:/python/untitled/study6/静态方法.py", line 24in nationality
        print('Bigberg is %s.' % self.country)
    AttributeError: type object 'Person' has no attribute 'country'
     
    # 提示没有一个 country 属性  

      2.3、访问类变量,即 全局属性/静态字段 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    class Person(object):
     
        country = 'Chinese'    # 增加一个 全局属性/静态字段
     
        def __init__(self, name, country):
     
            self.name = name
            self.country = country
     
        @classmethod
        def nationality(cls):    # 这里将sefl 改为 cls
            print('Bigberg is %s.' % cls.country)
     
    = Person('Bigberg''CN')
    p.nationality()
     
    # 输出
    Bigberg is Chinese.

    三、属性方法 

       3.1、定义

      属性方法的作用就是通过@property把一个方法变成一个静态属性 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Person(object):
     
        country = 'Chinese'
     
        def __init__(self, name, country):
     
            self.name = name
            self.country = country
     
        @property
        def drive(self):
            print('%s is driving a car.' % self.name)
    1
    2
    = Person('Bigberg''CN')
    p.drive()
    1
    # 输出 <br>Traceback (most recent call last): Bigberg is driving a car. File "G:/python/untitled/study6/静态方法.py", line 38, in <module> p.drive() TypeError: 'NoneType' object is not callable

      调用会出错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接p.drive就可以了

      正常调用: 

    1
    2
    3
    4
    5
    6
    = Person('Bigberg''CN')
    p.drive
     
    # 输出
     
    Bigberg is driving a car.

      3.2 setter用法

      如果我们想在属性方法里传参,比如车的品牌,我们就要用setter了,具体用法  @属性方法名.setter 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Person(object):
     
        country = 'Chinese'
     
        def __init__(self, name, country):
     
            self.name = name
            self.country = country
            self.car = "LAMBORGHINI"   # 定义车品牌为兰博基尼
     
        @property
        def drive(self):
            print('%s is driving a %s.' % (self.name, self.car))
     
    = Person('Bigberg''CN')
    p.drive
     
    # 输出
    Bigberg is driving a LAMBORGHINI.

      很显然我们开出去的车就是兰博基尼,如果我们想自己传入车品牌呢?比如 特斯拉: 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    class Person(object):
     
        country = 'Chinese'
     
        def __init__(self, name, country):
     
            self.name = name
            self.country = country
            self.car = "LAMBORGHINI"   #当然这里也可以设置为私有属性
     
        @property
        def drive(self):  # 这里不能传参是因为调用的时候,p.drive 没有()了,不能传入
            print('%s is driving a %s.' % (self.name, self.car))
     
        @drive.setter     # 修饰方法drive,可以为属性赋值
        def drive(self, car):     # 我们要重新定义这个drive方法
            print("set car:", car)
            self.car = car
     
    = Person('Bigberg''CN')
    p.drive = 'Tesla'     # 给属性赋值
    p.drive
     
    #输出
     
    set car: Tesla
    Bigberg is driving a Tesla.

      3.3 deleter 用法

      用来删除属性方法,具体用法 @属性方法名.deleter  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 以上例
    # 我们可以发现普通属性是可以通过del直接删除的
    # 比如
    print(p.name)
    del p.name
    print(p.name)
     
    # 输出
     
    Traceback (most recent call last):
    Bigberg
      File "G:/python/untitled/study6/静态方法.py", line 49in <module>
        print(p.name)
    AttributeError: 'Person' object has no attribute 'name'
     
    #删除之后就不能再调用了

      但是我们用del p.drive这种方法来删除属性方法是行不通的:

    1
    2
    3
    4
    5
    6
    7
    del p.drive
     
    #输出
    Traceback (most recent call last):
      File "G:/python/untitled/study6/静态方法.py", line 51in <module>
        del p.drive
    AttributeError: can't delete attribute

      所以我们就要用到 deleter方法: 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class Person(object):
     
        country = 'Chinese'
     
        def __init__(self, name, country):
     
            self.name = name
            self.country = country
            self.car = "LAMBORGHINI"
     
        @property
        def drive(self):
            print('%s is driving a %s.' % (self.name, self.car))
     
        @drive.setter
        def drive(self, car):
            print("set car:", car)
            self.car = car
     
        @drive.deleter   # 修饰 drive 方法,可以删除属性
        def drive(self):   # 重新定义 drive方法
            del self.car    #  删除的是属性
            print("扣了你的车,让你开豪车...")
     
    p.drive = 'Tesla'
    p.drive
     
    del p.drive  
     
    # 输出
    set car: Tesla
    Bigberg is driving a Tesla.
    扣了你的车,让你开豪车...

      让我们在秋名山再开一次车...

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    p.drive
     
    # 输出
    扣了你的车,让你开豪车...
    Traceback (most recent call last):
      File "G:/python/untitled/study6/静态方法.py", line 57in <module>
        p.drive
      File "G:/python/untitled/study6/静态方法.py", line 28in drive
        print('%s is driving a %s.' % (self.name, self.car))
    AttributeError: 'Person' object has no attribute 'car'
     
    # 提示没有这个属性了

    四、属性方法应用场景

    你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

    1. 连接航空公司API查询

    2. 对查询结果进行解析 

    3. 返回结果给你的用户

    因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心,用户只要知道结果就行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    class Flight(object):
     
        def __init__(self, name):
            self.name = name
     
        def check_status(self):
            print("checking flight %s status" % self.name)
            return 1
     
        @property
        def flight_status(self):
            status = self.check_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")
     
        @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...")
     
    = Flight('CA980')
    f.flight_status
    f.flight_status = 2
     
    #输出
     
    checking flight CA980 status
    flight is arrived...
    Has changed the flight status to  departured

    五、总结

    1.  静态方法是不可以访问实例变量或类变量的
    2. 类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
    3. 属性方法将一个方法变为类的属性,调用时不需要加()。有@property 、@属性方法名.setter、@属性方法名.deleter 三种装饰方法
  • 相关阅读:
    代码编写原则
    换个角度看世界
    不使用nib 文件时,需要改变一个view 的大小时,需要为viewcontroller添加loadView方法
    建议:一般地,建议使用xcode 4.3开发app 而不是使用xcode4.5
    iOS 5解决Could not instantiate class named NSLayoutConstraint问题
    访问对象方法比较
    让一个view 或者控件不支持拖拽
    Java Map遍历方式的选择
    Java里多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)
    java List集合记录 ArrayList和LinkedList的区别
  • 原文地址:https://www.cnblogs.com/wdbgqq/p/10162452.html
Copyright © 2020-2023  润新知