对于每一个类的成员而言都有两种形式:
私有成员和公有成员的访问限制不同:
静态字段(静态属性)
公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
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:非要访问私有成员的话,可以通过 对象._类__属性名,但是绝对不允许!!!*
*为什么可以通过._类__私有成员名访问呢?因为类在创建时,如果遇到了私有成员(包括私有静态字段,私有普通字段,私有方法)它会将其保存在内存时自动在前面加上_类名.*
类方法:
使用装饰器@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)
什么是特性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)
from collections import Iterable
from collections import Iterator
# 什么叫异常?
# 你的程序出现中断,飘红,致使你的整个项目中断了.
# 错误类型:
# 语法错误.
# 语法错误就不应该现在你的代码中.
# 逻辑错误:
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