封装
封装:将一些数据,重要的信息等等放到一个地方(空间中)
class A: country = 'China' area = '深圳' def __init__(self,name,age): self.name = name self.age = age a1 = A('小明',22) a2 = A('小华',23) print(a1.__dict__) print(a2.__dict__)
多态
python默认支持多态
i = 777alex
i = ‘我是字符串’
鸭子类型:python会约定俗成制定一些行为规范,保持一致性
类的约束
对类进行一些正确的引导,约束,统一规范,满足正确的可发方式
两种约束方法:
方法一:python常用的一种,在父类写一个相同的方法pay,在此方法里面,主动抛出一个错误(raise)

class A: # 这个父类制定了一个约束,规范,子类一定要有pay方法 def pay(self,money): raise Exception('未定义的方法') class Alipay(A): def pay(self,money): print('alipay') class QQpay(A): def zhifu(self,money): # 未按规定填写pay,而用了zhifu,会报 raise Exception('未定义的方法') 错误 print('QQpay') def pay(obj,money): obj.pay(money) q = QQpay() # pay(q,100) a = Alipay() pay(a,200)
方法二:在父类引用元类的抽象方法,抛出异常

from abc import ABCMeta,abstractmethod class A(metaclass=ABCMeta): # 这个父类制定了一个约束,规范,子类一定要有pay方法 ''' 抽象类,接口类:制定一个规范,强制执行。 ''' @abstractmethod def pay(self,money): raise Exception('未定义的方法') class Alipay(A): def pay(self,money): print('alipay') class QQpay(A): def zhifu(self,money): # 未按规定填写pay,而用了zhifu,会报 raise Exception('未定义的方法') 错误 print('QQpay') def pay(obj,money): obj.pay(money) q = QQpay() pay(q,100) # a = Alipay() # pay(a,200)
类的私有成员
class Boss: name = 'alex' # 公有静态属性 公有静态字段 __secretary =['女1', '男2', '眼膜'] # 私有静态属性 私有静态字段,有__表示 def __init__(self,username,password): self.username = username # 公有对象属性 公有普通字段 self.__password = password # 私有对象属性 私有普通字段 def func(self): # 用方法查看私有静态属性 print(self.__secretary) def __func(self): # 私有方法 print('经常跟秘书加班....') class Boss_son(Boss): def func(self): print(self.__secretary)
私有成员:私有静态属性,私有对象属性,私有方法
私有静态属性:
类外部不能访问,通过对象可以外部访问
私有方法:
类外部和派生类不能访问
类的类方法,静态方法
class A: name = 'barry' def __init__(self,a,b): # 双下方法 self.a = a self.b = b def func(self): # 普通方法,实例方法 pass @staticmethod # 静态方法 def func1(): print(666) @classmethod # 类方法 def func2(cls): print(777) @property # 属性 def bim(self): print(111)
类方法: @classmethod
类方法 他是通过类名直接调用的方法,类方法里面至少有一个参数,第一个参数默认cls
class A: name = 'ehco' @classmethod def func(cls): print(cls) print(111) def func1(self): print(self) A.func() # 可以直接用类名调用的方法,传的参数是类名 A.func1(123) # 和上面的作对比 ,这个需要传参 # 对象可否调用类方法? # 通过对象也可以调用类方法,cls 接受的不是对象空间而是类空间。 a = A() a.func() # <class '__main__.A'> 类名的内存地址
类方法在哪里用?
对类中的属性方法直接操作,与对象无关,这样才会用到类方法。
# 判断有多少人注册 class ClassTest(object): __num = 0 @classmethod def addNum(cls): cls.__num += 1 @classmethod def getNum(cls): return cls.__num # 这里我用到魔术函数__new__,主要是为了在创建实例的时候调用人数累加的函数。 def __new__(self): ClassTest.addNum() # 实例化一个对象,就调用一次addNum return super(ClassTest, self).__new__(self) #返回一个真正的__new__去创建空间 class Student(ClassTest): def __init__(self): self.name = '' a = Student() b = Student() print(ClassTest.getNum())
静态方法
为什么要静态方法;相似功能,保持一致性 @staticmethod
对象调用类里面的方法,不会影响方法的使用
import time class TimeTest(object): def __init__(self, hour, minute, second): self.hour = hour self.minute = minute self.second = second @staticmethod def showTime(): return time.strftime("%H:%M:%S", time.localtime()) print(TimeTest.showTime()) # 打印当前时间 t = TimeTest(2, 10, 10) # 示例对象t nowTime = t.showTime() # t调用静态方法,并不会改变方法的执行 print(nowTime) # 打印当前时间
类的属性: @property @xxx.setter @ xxx.deleter
@property:属性
将一个方法伪装成属性,虽然在代码逻辑上没什么提高。但是让其看起来更合理
# 调用的时候少一个括号,看着没什么用
class Bmi: def __init__(self,name,weight,height): self.name = name self.weight = weight self.height = height @property def bmi(self): return self.weight / self.height **2 pang = Bmi('小胖',75,1.76) # print(pang.bmi()) # 如果没有@property,调用的时候加() print(pang.bmi) # 如果有@property,调用的时候不要()
@xxx.setter @ xxx.deleter 这两个和@property一起使用
class Market: def __init__(self, name, price, discount): self.name = name self.__price = price # 私有属性 self.__discount = discount # 定义折扣 @property def price(self): # 返回折后价 return self.__price * self.__discount @price.setter def price(self, new_price): # 计算降价后的折扣价 self.__price = new_price / self.__discount @price.deleter def price(self): # 删除价格 del self.__price apple = Market('苹果',8,0.95) print(apple.price) apple.price = 7.5 # 看到改等式,就执行@price.setter。并把7.5传给 new_price print(apple.price) del apple.price # 看到del price,就执行@price.deleter print(apple.price)
异常处理 : 多种 try.......except.....
python解释器检测到错误,触发异常(也允许程序员自己触发异常
程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)
如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理
try: l1 = [1,2,3] l1[100] # list index out of range except Exception as e: print(e) print(111) # 程序即使有错误也不影响后面文件的执行 print(222) print(333)
单支 try except
try: l1 = [1,2,3] l1[100] # IndexError # 程序发现错误,直接跳到except。然后执行后续代码 print(333) print(5555) except IndexError as e: print(e) print(777)
多支 try except
try: l1 = [1,2,3] # l1[100] # IndexError print(333) print(5555) dic = {'key1':'v1'} dic['key2'] # KeyError num = int(input('请输入选项:')) print(777) except IndexError as e: print(e) except KeyError as e: print(e)
接收所有错误:try .except EXCEPOTION
try: l1 = [1,2,3] # l1[100] # IndexError print(333) print(5555) dic = {'key1':'v1'} # dic['key2'] # KeyError num = int(input('请输入选项:')) print(777) except Exception as e: # 接收所有错误 print(e)
# 以上这三种分情况讨论:
# 1,如果你对报错信息不关系,只是想直接跳过报错而不分流执行代码。 万能异常最好。
# 2,如果你想要捕捉具体的错误信息,根据不同的错误执行不同的分支。多分支比较好。
try expcet else
出现异常不执行else语句,没有异常就执行else语句
try: l1 = [1, 2, 3] l1[100] # IndexError except IndexError: print(666) else: print('出现异常不执行else语句,没有异常就执行else语句')
try except finally 有没有错误finally都会执行
用处: 关闭文件句柄,断开数据库连接
try: l1 = [1, 2, 3] # l1[100] # IndexError dic = {} dic['key1'] except IndexError: print(666) else: print('出现异常不执行else语句,没有异常就执行else语句') finally: print('finally有没有异常都执行finally语句') finally有没有异常都执行finally语句,要他有何用? 1,关闭文件句柄,数据库链接等。 with open('log',encoding='utf-8') as f1: try: # f1.read() 好几千代码 finally: f1.close()
# 函数,return 循环的break 之前执行finally操作。 def func(): try: return 666 finally: print(111) # 会执行 func()
while被break打断,finally也会执行 while 1: try: break finally: print(777)
raise 主动抛出错误
class MyError(BaseException): # 自定义一个错误 pass try: raise MyError('我的错误') # 主动跑出自定义错误 except MyError as e: print(e)
assert 1 == 2