zoukankan      html  css  js  c++  java
  • python类的高级属性

    ---恢复内容开始---

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

    class Person(object):
        def __init__(self,name):
            self.name = name
        @classmethod
        def eat(self):
    
            print("%s is eating"%self.name)
    d = Person("alex")
    d.eat()

    报错如下:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/类方法.py
    Traceback (most recent call last):
      File "D:/python开发代码/Python之路/作业/day8/类方法.py", line 9, in <module>
        d.eat()
      File "D:/python开发代码/Python之路/作业/day8/类方法.py", line 7, in eat
        print("%s is eating"%self.name)
    AttributeError: type object 'Dog' has no attribute 'name'

    定义一个类变量后,代码如下:

    class Person(object):
        name = "parktrick"
        def __init__(self,name):
            self.name = name
        @classmethod
        def eat(self):
    
    
            print("%s is eating"%self.name)
    d = Person("alex")
    d.eat()

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/类方法.py
    parktrick is eating
    
    Process finished with exit code 0

    静态方法:@staticmethod装饰器即可把其装饰的方法变为一个静态方法,静态方法的特点是不可以访问实例变量或类变量,但是可以调用时主动传递实例本身给eat方法,即d.eat(d),操作代码如下:

    未使用类名调用方法的场景:

    class Dog(object):
        def __init__(self,name):
            self.name = name
        @staticmethod #把eat变成静态方法
        def eat(self):
            print("%s is eating"%self.name)
    d = Dog("alex")
    #调用时主动传递实例本身给eat方法,即d.eat(d)
    d.eat()

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/静态方法.py
    Traceback (most recent call last):
      File "D:/python开发代码/Python之路/作业/day8/静态方法.py", line 9, in <module>
        d.eat()
    TypeError: eat() missing 1 required positional argument: 'self'
    
    Process finished with exit code 1

    报错显示eat方法需要个参数,但我们明明传了alex啊,所以说静态方法无法访问实例中的变量,那定义一个类变量呢?看下面:

    class Dog(object):
        name = "parktrick" #定义了一个类变量,看看运行结果
        def __init__(self,name):
            self.name = name
        @staticmethod #把eat变成静态方法
        def eat(self):
            print("%s is eating"%self.name)
    d = Dog("alex")
    #调用时主动传递实例本身给eat方法,即d.eat(d)
    d.eat()

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/静态方法.py
    Traceback (most recent call last):
      File "D:/python开发代码/Python之路/作业/day8/静态方法.py", line 10, in <module>
        d.eat()
    TypeError: eat() missing 1 required positional argument: 'self'
    
    Process finished with exit code 1

    结果显示报错,所以由此可以看出静态方法无法访问实例变量和类变量

    看看正确姿势,通过调用时主动传递实例本身给eat方法,代码如下:

    class Dog(object):
        # name = "parktrick"
        def __init__(self,name):
            self.name = name
        @staticmethod #把eat变成静态方法
        def eat(self):
            print("%s is eating"%self.name)
    d = Dog("alex")
    #调用时主动传递实例本身给eat方法,即d.eat(d)
    d.eat(d)

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/静态方法.py
    alex is eating
    
    Process finished with exit code 0

     属性方法:通过@property把一个方法变成一个静态属性,既然是属性,就可以直接使用实例化对象调用了,比如d.walk,代码如下:

    class Person(object):
        def __init__(self,name):
            self.name = name
        @property
        def walk(self):
            print("%s is walking"%self.name)
    test = Person("Parktrick")
    test.walk  #直接使用实例化对象调用walk,不用加小括号

    运行结果如下:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/属性方法.py
    Parktrick is walking
    
    Process finished with exit code 0

    如果加了括号就会报错了,结果如下所示:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/属性方法.py
    Traceback (most recent call last):
      File "D:/python开发代码/Python之路/作业/day8/属性方法.py", line 8, in <module>
        test.walk()
    TypeError: 'NoneType' object is not callable
    Parktrick is walking

    静态属性的作用:

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

    1. 连接航空公司API查询

    2. 对查询结果进行解析 

    3. 返回结果给你的用户

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

    class Flight(object):
        def __init__(self,name):
            self.flight_name = name
        def check_status(self):
            print("check flight %s status" %self.flight_name)
            return 1
        @property
        def flight_status(self):
            status = self.check_status()
            # print(status)
            if status == "1":
                print("飞机已起飞")
            elif status == "2":
                print("飞机未起飞")
            elif status == "3":
                print("飞机就没有飞过")
        @flight_status.setter #修改
        def flight_status(self,status):
            status_dic = {
                0:"flying",
                1:"not flying",
                2:"none flying"
            }
            print("33[31mHas changed the flight status to 33[0m",status_dic.get(status))
    
    test = Flight("国航")
    # test.check_status()
    test.flight_status
    test.flight_status = 2

    运行结果如下:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/航班.py
    check flight 国航 status
    Has changed the flight status to  none flying
    
    Process finished with exit code 0

    再看一个廖大神举的例子:

    class Student(object):
        @property
        def score(self):
            return self._score
        @score.setter
        def score(self,value):
            if not isinstance(value,int):
                raise ValueError("score must be an integer")
            if value < 0 or value > 100:
                raise  ValueError("score must be 0-100")
            self._score = value
    test = Student()
    test.score = 100
    print(test.score)

    总而言之,Python内置的@property装饰器就是负责把一个方法变成属性调用的。

    类的特殊成员方法

    __doc__

    class Person(object):
        '''测试类的成员变量'''
        def walk(self):
            pass
    P = Person()
    print(P.__doc__)

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/类的特殊成员便令.py
    测试类的成员变量
    
    Process finished with exit code 0

     __dict__ 查看类或对象中的所有成员

    class Province:
        country = "china"
        def __init__(self,name,count):
            self.name = name
            self.count = count
        def func(self,*args,**kwargs):
            print("func")
    #获取类的成员,即:静态字段、方法
    print(Province.__dict__)
    
    obj1 = Province("Hebei",10000)
    print(obj1.__dict__)
    #获取对象obj1的成员

    __getitem__、__setitem__、__delitem__

    class Foo(object):
        def __getitem__(self, key):
            print('__getitem__', key)
    
        def __setitem__(self, key, value):
            print('__setitem__', key, value)
    
        def __delitem__(self, key):
            print('__delitem__', key)
    obj = Foo()
    result = obj["k1"] #自动触发执行__getitem__
    obj["k2"] = "alex" #自动触发执行__setitem
    del obj["k1"]

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/类的特殊成员便令.py
    __getitem__ k1
    __setitem__ k2 alex
    __delitem__ k1
    
    Process finished with exit code 0

    反射:通过字符串映射或修改程序运行时的状态、属性、方法

    利用反射查看面向对象成员归属

    class Foo:
        def __init__(self,name):
            self.name = name
        def show(self):
            print("show")
    obj = Foo("as")
    #如果是类,就可以找到类中成员,运行结果为Bool值,找到了就显示True,没找到就显示False
    print(hasattr(Foo,"show"))
    #如果是对象,既可以找到对象,也可以找到类中的成员
    print(hasattr(obj,"name")) print(hasattr(obj,"show"))

    运行结果:

    C:python3.5python.exe D:/python开发代码/Python之路/作业/day8/类的特殊成员便令.py
    True
    True
    True
    
    Process finished with exit code 0

    未完待续。。。。

  • 相关阅读:
    Chp18: Hard
    内存泄漏 和 内存溢出
    Chp4: Trees and Graphs
    trie树--详解
    Tries
    Comparable & Comparator
    memory leak
    8个月从CS菜鸟到拿到Google Offer的经历+内推
    Word Ladder II
    Java垃圾回收机制
  • 原文地址:https://www.cnblogs.com/uglyliu/p/6118871.html
Copyright © 2011-2022 走看看