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.5\python.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.5\python.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.5\python.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.5\python.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.5\python.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.5\python.exe D:/python开发代码/Python之路/作业/day8/属性方法.py Parktrick is walking Process finished with exit code 0
如果加了括号就会报错了,结果如下所示:
C:\python3.5\python.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("\033[31mHas changed the flight status to \033[0m",status_dic.get(status)) test = Flight("国航") # test.check_status() test.flight_status test.flight_status = 2
运行结果如下:
C:\python3.5\python.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.5\python.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.5\python.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.5\python.exe D:/python开发代码/Python之路/作业/day8/类的特殊成员便令.py
True
True
True
Process finished with exit code 0
未完待续。。。。