Python------类的结构细分,异常处理,方法,属性

it2022-05-05  84

1.类的私有成员

对于每一个类的成员而言都有两种形式:

公有成员,在任何地方都能访问私有成员,只有在类的内部才能方法

私有成员和公有成员的访问限制不同:

静态字段(静态属性)

公有静态字段:类可以访问;类内部可以访问;派生类中可以访问

class C: name = "公有静态字段" def func(self): print C.name class D(C): def show(self): print C.name C.name # 类访问 obj = C() obj.func() # 类内部可以访问 obj_son = D() obj_son.show() # 派生类中可以访问

私有静态字段:仅类内部可以访问;

class C: __name = "私有静态字段" def func(self): print C.__name class D(C): def show(self): print C.__name C.__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.__num a = Student('太白金星', 18) b = Student('武sir', 36) c = Student('alex', 73) print(Student.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) 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.aaa print(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 Iterator

s1 = '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: # pass 5.异常处理其他成员 # 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('触发了连接异常') # 异常处理总结: # 异常处理不能经常使用:异常处理耗费性能.有些错误是需要进行分流使用.代码的可读性变差. # 关键节点使用.

转载于:https://www.cnblogs.com/hql1117/p/11171800.html


最新回复(0)