property 特性
什么是特性property
property 是一种特殊的属性,访问它时会执行一段功能(函数),然后返回值
例如
BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24-27 肥胖:28-32 非常肥胖, 高于32 体质指数(BMI)=体重(kg)÷身高^2(m) EX:70kg÷(1.75×1.75)=22.86 ''' class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height def bmi(self): return self.weight / (self.height * self.height) egon=People('egon',75,1.80) print(egon.bmi())
#结果为 23.148148148148145
#首先需要明确的是 bmi 是算出来的 , 不是一个固定死的值, 也就是说我们必须编写一个功能,
每次调用该功能,都会立即算出一个值。所以将其做成了一个函数。
以上虽然方便,但是bmi的值听起来更像一个名词而非动词。 一般名词我们调用一个名词属性就
就像调用名字那样去调用 egon.bmi 而不是像函数那样去调用不用egon.bmi()
所以我们还需要将其更近一下。这就用到了 封装中的property.
它就相当于一个装饰器,我们为bmi这个函数添加装饰器, 将其伪装成一个数据属性
class People: def __init__ (self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height*self.height) p1= ('egon',70,1.80) print(p1.bmi) # 结果为 23.148148148148145
若是我们想改其中的数值 可以这样更改
class People: def __init__(self,name,weight,height): self.name=name self.weight=weight self.height=height @property def bmi(self): return self.weight / (self.height * self.height) p1=People('egon',75,1.80) p1.weight=70 # 将其中的体重改为70 , 得到的bmi 值又会更改 print(p1.bmi) #打印结果 21.604938271604937
二 多态:
多态值得是同一种事物多种形态
为什么要用多态
用基类创建一套统一的规则。强制子类去遵循(使用抽象类实现),这样便可以在不用考虑
对象具体类型的前提下而直接使用对象的下的方法。
如何使用多态:
例如猫,狗 猪都是动物 他们都有叫的功能,我们可以在父类中定义好他们的功能,然后不用管子类是猫还是狗还是猪,可以直接调用动物的属性,而不用去考虑他是狗还是猫还是猪。但是在工作中 有可能会是动物是一个人定义的 猫狗猪需要另外一个人来定义, 那么就有可能出现定义猫狗猪的程序员不会按照动物的属性去定义, 那么那样去定义的时候 就需要记住是哪个动物的属性了, 这样无形中就增加的来历复杂度。例如:
class animal: def speak(self) pass class Cat(animal): def jiao(self): print('喵喵喵‘) class Dog(animal): def speak(self): print('汪汪汪') class Pig(animal): def han(self): print('哼哼哼') #同样都是动物的叫声 要是调用的话 就必须得调用具体动物的属性才可以 : c=Cat() d=Dog() p=Pig() c.jiao() d.speak() p.han() 这样就比较麻烦了
现在我们就可以考虑到多态的好处了,
接下来说如何用
再父类的上面加上@ abc #abc=abstract class, 然后在共同属性函数上 加上这个abc 装饰器
@abc,abstractmethod 这样子类中的属性就必须要同父类属性一致 ,否则就会报错
import abc #abc=abstract class class animal: @abc.abstractmethod #加上装饰器 这样子类属性就必须要父类一致,否则无法调用 def eat(self): pass @abc.abstractmethod def drink(self): pass @abc.abstractmethod def run(self): pass @abc.abstractmethod def bark(self): pass class Cat(animal): def eat(self): print('cat eat') def drink(self): print('cat drink') def run(self): print('cat run') def bark(self): print('喵喵喵') class Dog(animal): def eat(self): print('dog eat') def drink(self): print('dog drink') def run(self): print('dog run') def bark(self): print('汪汪汪') class Pig(animal): def eat(self): print('pig eat') def drink(self): print('pig drink') def run(self): print('pig run') def bark(self): print('哼哼哼') c=Cat() d=Dog() p=Pig() c.eat() c.bark() c.run() c.drink()
三 鸭子类型
python 崇尚鸭子类型, 即‘如果看起来像, 叫声像, 而且走起路来像鸭子, 那么它就是鸭子’
python程序员通常根据这种行为来编写程序, 例如,如果想编写现有对象的自定义版本,可以继承该对象,也可以创建一个外观和行为像,但是与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。
class Foo: def f1(self): print('from foo.f1') def f2(self): print('from foo.f2') class Bar: def f1(self): print('feom bar.f1') def f2(self): print('from bar.f2') obj1 =Foo() obj2 =Bar() obj1.f1() obj1.f2() obj2.f1() obj2.f2()
这就是鸭子类型
四 绑定方法 classmethod 与 非绑定方法 staticmethod
类中定义的函数分为两大类:
一:绑定方法(绑定给谁, 谁来调用就自动将它本身当做第一个参数传入):
绑定对象的方法特殊之处:
应该由对象来调用 ,对象来调用,会自动将对象当做第一个参数传入
绑定到类的方法:用classmethod 装饰器装饰的方法。
classmethod 是给类用的,即绑定到类, 类在使用是会将本身当做参数传给类方法的第一个参数,(即便是对象来调用也会将类当做第一个参数传入,)python为我们内置了函数classmethod 来把类中的函数定义成类方法。
import setting #导入模块里的 class People: def __init__(self,name,age): self.name=name self.age=age def tell(self): print('%s:%s'%(self.name,self.age)) @classmethod #给类使用 def from_conf(cls): return cls(setting.NAME,setting.AGE) p=People.from_conf() p.tell()
非绑定方法 staticmethod 就是一个普通函数,
特性 即不跟类绑定, 也不跟对象绑定, 这意味着谁都能用,
谁来用都是一个普通函数, 也就是说没有自动传值的特性了
import settings import hashlib import time class People: def __init__(self,name,age): self.uid=self.create_id() self.name=name self.age=age def tell(self): print('%s: %s:%s' %(self.uid,self.name,self.age)) @classmethod def from_conf(cls): return cls(settings.NAME,settings.AGE) @staticmethod def create_id(): m=hashlib.md5() m.update(str(time.clock()).encode('utf-8')) return m.hexdigest() obj=People('egon',18) # print(obj.uid,obj.name,obj.age) # obj.tell() # print(obj.create_id) # print(People.create_id) print(obj.create_id()) print(People.create_id())