1.类的私有成员
对于每一个类的成员而言都有两种形式:
- 公有成员,在任何地方都能访问
- 私有成员,只有在类的内部才能方法
私有成员和公有成员的访问限制不同:
静态字段(静态属性)
公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
class C: name = "公有静态字段" def func(self): print C.nameclass D(C): def show(self): print C.nameC.name # 类访问obj = C()obj.func() # 类内部可以访问obj_son = D()obj_son.show() # 派生类中可以访问
私有静态字段:仅类内部可以访问;
class C: __name = "私有静态字段" def func(self): print C.__nameclass D(C): def show(self): print C.__nameC.__name # 不可在外部访问obj = C()obj.__name # 不可在外部访问obj.func() # 类内部可以访问 obj_son = D()obj_son.show() #不可在派生类中可以访问
普通字段(对象属性)
公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
class C: def __init__(self): self.foo = "公有字段" def func(self): print self.foo # 类内部访问class D(C): def show(self): print self.foo # 派生类中访问obj = C()obj.foo # 通过对象访问obj.func() # 类内部访问obj_son = D();obj_son.show() # 派生类中访问
私有普通字段:仅类内部可以访问;
class C: def __init__(self): self.__foo = "私有字段" def func(self): print self.foo # 类内部访问class D(C): def show(self): print self.foo # 派生类中访问obj = C()obj.__foo # 通过对象访问 ==> 错误obj.func() # 类内部访问 ==> 正确obj_son = D();obj_son.show() # 派生类中访问 ==> 错误
方法:
公有方法:对象可以访问;类内部可以访问;派生类中可以访问
class C: def __init__(self): pass def add(self): print('in C')class D(C): def show(self): print('in D') def func(self): self.show()obj = D()obj.show() # 通过对象访问 obj.func() # 类内部访问 obj.add() # 派生类中访问
私有方法:仅类内部可以访问;
class C: def __init__(self): pass def __add(self): print('in C')class D(C): def __show(self): print('in D') def func(self): self.__show()obj = D()obj.__show() # 通过不能对象访问obj.func() # 类内部可以访问obj.__add() # 派生类中不能访问
总结:
对于这些私有成员来说,他们只能在类的内部使用,不能再类的外部以及派生类中使用.
*ps:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!*
*为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.*
2.类方法与静态方法
类方法:
使用装饰器@classmethod。
原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。
class Student: __num = 0 def __init__(self,name,age): self.name = name self.age= age Student.addNum() # 写在__new__方法中比较合适,但是现在还没有学,暂且放到这里 @classmethod def addNum(cls): cls.__num += 1 @classmethod def getNum(cls): return cls.__numa = Student('太白金星', 18)b = Student('武sir', 36)c = Student('alex', 73)print(Student.getNum())
静态方法 :
使用装饰器@staticmethod。
静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。
import timeclass 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)nowTime = t.showTime()print(nowTime)
3.属性
什么是特性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 @property def bmi(self): return self.weight / (self.height**2)p1=People('egon',75,1.85)print(p1.bmi)
为什么要用property
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则
由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
class Foo: def __init__(self,name): self.name = name @property def aaa(self): print('111') # 获取,运行这 @aaa.setter def aaa(self): print('222') # 修改,运行这 @aaa.deleter def aaa(self): print('333') # 删除,修改这obj = Foo('alex')obj.name = 'dsb'obj.aaa = '太白'del obj.aaaprint(obj.name)
4.isinstance issubclass type.py
class A:
pass
class B(A):
pass
class C(B):
pass
obj = B()
print(isinstance(obj, B))
print(isinstance(obj, A))
print(isinstance(obj, C))
对象与类之间的关系
isinstance(obj,N): 判断 obj对象 是由N类(N的派生类)实例化的对象 返回 True.
print(isinstance(obj, A))
class A:
pass
class B(A):
pass
class C(B):
pass
类与类之间的关系
issubclass(M,N) 判断是M类是N类的子孙.
print(issubclass(C, B))
print(issubclass(C, A))
from collections import Iterable
from collections import Iterators1 = 'seewfsdkfl' # class str(Iterable) Iterable
l1 = [1, 2, 3]
print(type(s1)) # 判断的是对象从属于哪个类
print(type(l1))
print("iter" in dir(s1))
print(isinstance(s1, Iterable))
type 到底是什么?
type 元类 python中一切皆对象 , 一个类也是一个对象.
么这个(类)对象肯定是由类实例化出来的.
python中你创建的所有类,以及大部分list str等等这些类,都是从type元类实例化得来的.
python中继承object类都是新式类.
object 也是由type元类实例化得来的.
5.异常处理
# 什么叫异常?# 你的程序出现中断,飘红,致使你的整个项目中断了.# 错误类型:# 语法错误.# 语法错误就不应该现在你的代码中.# 逻辑错误:1.用if进行异常处理# num = input('请输入:')# if num.isdecimal():# num = int(num)# if 0 < num < 6 :# pass# elif num == 10:# pass# else:# pass# 2.try单分支# try:# l1 = [1,2,3]# print(l1[100])# dic = {1: 2,'a': 'b'}# print(dic[3])# num = input('请输入序号')# int(num)# except IndexError as e:# # print('处理了索引错误')# print(e)# print(111)# print(222)try多分支# try:# # l1 = [1,2,3]# # print(l1[100])# # dic = {1: 2,'a': 'b'}# # print(dic[3])# num = input('请输入序号')# int(num)# except IndexError as e:# print('处理了索引错误')# except KeyError as e:# print('没有此键')# except ValueError as e:# print('出现了转化错误')# print(111)# print(222)# 及时解决异常,避免程序中断.# 程序的分流.dic = { 1: 111, 2: 333, 3: 555,}# while 1:# try:# num = input('请输入序号')# int(num)# print(dic[int(num)])# except KeyError as e:# print('选项超出范围,请重新输入')# except ValueError as e:# print('请输入数字')# print(111)# print(222)3.万能异常# try:# num = input('请输入序号')# int(num)# print(dic[int(num)])# except Exception as e:# print(e)# print(111)# 什么时候用万能异常,什么时候用多分支?#如果你只是想把这个异常处理掉,让程序继续执行. 万能异常.# 如果出现了异常,你是想根据不同的异常执行不同的逻辑流程,你要采取多分支.4.万能 + 多分支# dic = {# 1: 111,# 2: 333,# 3: 555,# }# while 1:# try:# num = input('请输入序号')# int(num)# print(dic[int(num)])# except KeyError as e:# print('选项超出范围,请重新输入')# except ValueError as e:# print('请输入数字')# except Exception:# pass5.异常处理其他成员# try:# num = input('请输入序号')# int(num)# print(dic[int(num)])# except KeyError as e:# print('选项超出范围,请重新输入')# except Exception:# pass# # else: # 如果上面无异常执行else语句,否则不执行else语句.# # print(666)# finally: # 在整个程序终止之前,执行finally# print('执行finally')# 1. 文件操作# try:# f = open('register', mode='w')# f.write('fdjsaklfd')# f.write('fdjsaklfd')# f.write('fdjsaklfd')# l1 = [1, 2, 3]# print(111)# print(l1[1000])# f.write('fdjsaklffjdsklaf')# finally:# print('哈哈哈哈') # f.close()# 数据库: 连接数据库引擎.# try:# int('e')# finally:# print(777)# 在函数中 finally.# 结束函数之前,先要执行finally语句.# def func():# try:# a = 1# b = 2# return a + b# finally:# print(666)# func()6.主动抛出异常:# raise Exception('fdkslafjdslkf')7.断言:# assert 条件 # 源码上assert.# assert 1 == 2# print(11)# print(22)# print(33)8.自定义异常(了解)# TypeError# class Connection(BaseException):# def __init__(self,msg):# self.msg = msg# raise Connection('触发了连接异常')# 异常处理总结:# 异常处理不能经常使用:异常处理耗费性能.有些错误是需要进行分流使用.代码的可读性变差.# 关键节点使用.