一、封装
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
BMI指数(bmi是计算而来的,但是明显是一个类的属性而不是一个方法,如果我们将它做成一属性更便于理解)

1 class People: 2 def __init__(self,name,hight,weight): 3 self.name=name 4 self.hight=hight 5 self.weight=weight 6 7 @property 8 def bim(self): 9 return self.weight/(self.hight**2) 10 11 lzy=People('lzy',1.1,16) 12 lg=People('lg',1.7,75) 13 14 lg.weight=70 15 print(lzy.bim) 16 print(lg.bim)
首先需要明确,bmi是算出来的并不是一个固定的值,所以要编写一个功能,每次调用该功能都会立即计算一个值
于是我们就可以把bmi这个函数添加装饰器,将其伪装成一个数据属性
因为虽然伪装成一个数据属性但其还是一个方法不能直接给它附值

1 class People: 2 def __init__(self,name): 3 self.__name=name 4 5 6 @property 7 def name(self): #obj.name 8 print('您现在访问的是用户名。。。') 9 return self.__name 10 11 @name.setter #obj.name='EGON' 12 def name(self,x): 13 # print('=================',x) 14 if type(x) is not str: 15 raise TypeError('名字必须是str类型,傻叉') 16 self.__name=x 17 18 @name.deleter 19 def name(self): 20 # print('就不让你删') 21 del self.__name 22 23 obj=People('egon') 24 25 print(obj.name) 26 print(obj.name()) 27 28 print(obj.name) 29 30 obj.name='EGON' 31 32 print(obj.name) 33 34 obj.name=123 35 36 del obj.name
二、多态
多态指的是同一种事物多种形态
就是用基类创建一套统一的规则,强制子类去遵循,这样便可以在不用考虑对象具体类型的前提下而
直接使用对象下的方法
class Animal:
def eat(self)
pass
def drink(self)
pass
class Cat(Animal)
def eat(self):
print('aaa')
class Dog(Animal):
def eat(self):
print('bbb')
c=cat()
c.eat()
c.drink()
多态性:可以在不用考虑对象具体类型的前提下而直接使用对象下的方法
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.absstractmethod
def eat(self):
pass
@abc.abstractmethod
def drink(self):
pass
obj=Animal()基类基本是不能用来实例化的
class Cat(Animal):
def eat(self):
print('cat eat')
def drink(self):
print('cat drink')
c=Cat()
c.bark()
def BARK(animal):
animal.bark()
bark(c)
1.增加了程序的灵活性
以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
2.增加了程序额可扩展性
通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
三 鸭子类型
Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’
例如,如果想编写现有对象的自定义版本,可以继承该对象也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度
class Foo:
def f1(self):
print('from foo.f1')
def f2(self):
print('from bar.f1')
class Bar:
def f1(self):
print('from bar.f1')
def f2(self):
print('from bar.f2')
obj1=Foo()
obj2=Bar()
obj1.f1()
obj1.f2()
obj2.f1()
obj2.f2()
绑定方法:
1、绑定方法:
在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法
绑定对象的方法特殊之处:
应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入
绑定到类的方法特殊之处:
应该由类来调用,类来调用,会自动将类当作第一个参数传入
import settings
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(settings.Name,settings.AGE)
staticmethod:非绑定方法,就是一个普通函数
特性:既不跟类绑定,也不跟对象绑定,这就意味着谁能调用
谁来用都是一个普通函数,也就是说没有自动传值的特性了
import setting,hashlib,time
class People:
def __init__(self,name,age):
self.uid=self.creater_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(setting.NaME,settings.AGE)
@staticmethod
def creater_id():
m=hashlib.md5()
m.update(str(time.clock()).encode('utf-8'))
return m.hexdigest()
obj=People('egon',18)