Python类的介绍
类提供了一种组合数据和功能的方法。 创建一个新类意味着创建一个新的对象 类型,从而允许创建一个该类型的新 实例 。 每个类的实例可以拥有保存自己状态的属性。 一个类的实例也可以有改变自己状态的(定义在类中的)方法。
和其他编程语言相比,Python 用非常少的新语法和语义将类加入到语言中。它是 C++ 和 Modula-3 中类机制的结合。Python 的类提供了面向对象编程的所有标准特性:类继承机制允许多个基类,派生类可以覆盖它基类的任何方法,一个方法可以调用基类中相同名称的的方法。对象可以包含任意数量和类型的数据。和模块一样,类也拥有 Python 天然的动态特性:它们在运行时创建,可以在创建后修改。
1.类的构造
1.1类的构造函数
class DemoClass(object):
"类描述"
def __init__(self,name):
print(name)
dc1=DemoClass("老王")
dc2=DemoClass("老李")
1.2类的属性
class DemoClass(object):
count=0
def __init__(self,name,age):
self.name=name
self.age=age
DemoClass.count +=1
dc1=DemoClass("老王",45)
dc2=DemoClass("老李",51)
print("总数:",DemoClass.count)
print(dc1.name,dc2.name)
1.3类描述
class xuehang(object):
"描述部分"
pass
print(xuehang.__doc__)
1.4类构造方法
#实例方法:实例对象的方法,由各实例对象共享,最常用的形式
class DemoClass(object):
def __init__(self,name):
self.name=name
def lucky(self):
s=0
for c in self.name:
s+=ord(c)%100
return s
dc1=DemoClass("老王")
dc2=DemoClass("老李")
print(dc1.name,"的幸运数字是:",dc1.lucky())
print(dc2.name,"的幸运数字是:",dc2.lucky())
#类方法:类对象的方法,由所有实例对象共享
class DemoClass(object):
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
@classmethod
def getChrCount(cls):
s="零一二三四五六七八九十多"
return s[DemoClass.count]
dc1=DemoClass("老王")
dc2=DemoClass("老李")
print(dc1.getChrCount())
print(DemoClass.getChrCount())
#自由方法:类中的一个普通函数,由类所在的命名空间管理,类对象独享
class DemoClass(object):
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
def foo():
DemoClass.count*=100
return DemoClass.count
dc1=DemoClass("老王")
print(DemoClass.foo())
#静态方法:类中的一个普通函数,由类对象和实例对象共享
class DemoClass(object):
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
@staticmethod
def foo():
DemoClass.count*=100
return DemoClass.count
dc1=DemoClass("老王")
print(DemoClass.foo())
print(dc1.foo())
#保留方法:由双下划线开始和结束的方法,保留使用,如__len__()
class DemoClass(object):
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
def __len__(self):
return len(self.name)
dc1=DemoClass("老王")
dc2=DemoClass("诸葛亮")
print(len(dc1))
print(len(dc2))
1.5类的析构函数
#使用del删除对象且对象被真实删除时调用析构函数__del__()
class DemoClass(object):
def __init__(self,name):
self.name=name
def __del__(self):
print("再见",self.name)
dc1=DemoClass("老王")
del dc1
# 使用del删除对象且对象被真实删除时调用析构函数__del__()
# 调用条件:当实例对象被真实删除时,才调用该函数内语句
# 真实删除:当前对象的引用数为0或当前程序退出(垃圾回收)
class DemoClass(object):
def __init__(self,name):
self.name=name
def __del__(self):
print("再见",self.name)
dc1=DemoClass("老王")
dc2=dc1
del dc1
print(dc2.name)
# 使用del删除对象且对象被真实删除时调用析构函数__del__()
# 调用条件:当实例对象被真实删除时,才调用该函数内语句
# 真实删除:当前对象的引用数为0或当前程序退出(垃圾回收)
#sys.getrefcount() 返回对象引用次数的方法,辅助删除对象时的分析
#sys.getrefcount()函数返回值为被引用值+1 非特定目的,不建议自己撰写析构函数,利用Python的垃圾回收机制
import sys
class DemoClass(object):
def __init__(self,name):
self.name=name
def __del__(self):
return "再见"+self.name
dc1=DemoClass("老王")
dc2=dc1
print(sys.getrefcount(dc1))
2.类的封装私有属性和公开属性
2.1私有类属性
class DemoClass(object):
__count=0#私有类属性定义
def __init__(self,name):
self.name=name
DemoClass.__count+=1#私有类属性的内部使用
@classmethod
def getCount(cls):
return DemoClass.__count#私有属性的内部使用
dc1=DemoClass("老王")
dc2=DemoClass("老李")
print(DemoClass.getCount())#类的类方法,外部使用
2.2私有实例属性
class DemoClass(object):
def __init__(self,name):
self.__name=name#私有实例属性定义
def getName(self):
return self.__name#私有实例属性内部使用
dc1=DemoClass("老王")
dc2=DemoClass("老李")
print(dc1.getName(),dc2.getName())#对象的方法
print(dc1._DemoClass__name)
2.3私的私有方法
class DemoClass(object):
def __init__(self,name):
self.__name=name
def __getName(self):
if self.__name!="":
return self.__name
else:
return "老张"
def printName(self):
return "{}同志".format(self.__getName())
dc1=DemoClass("老王")
dc2=DemoClass("")
print(dc1.printName(),dc2.printName())
3.类的继承
3.1类继承的构建
class DemoClass(object):#基类
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
def getName(self):
return self.name
class HumanNameClass(DemoClass):#派生类
def printName(self):
return str(DemoClass.count)+self.name#对基类类属性的使用
dc1=HumanNameClass("老王")#派生类的实例对象
print(dc1.getName())#对基类实例方法的使用
print(dc1.printName())#对派生类实例方法的使用
class DemoClass(object):#基类
count=0
def __init__(self,name):
self.name=name
DemoClass.count+=1
def getName(self):
return self.name
class HumanNameClass(DemoClass):#派生类
def printName(self):
return str(DemoClass.count)+self.name#对基类类属性的使用
dc1=HumanNameClass("老王")#派生类的实例对象
print(isinstance(dc1,DemoClass))#判断对象obj是否是类cls的实例或子类实例,返回Turn或False
print(isinstance(dc1,HumanNameClass))#判断对象obj是否是类cls的实例或子类实例,返回Turn或False
print(issubclass(HumanNameClass,DemoClass))#判断类cls1是否是类cls2的子类,返回Turn或False
3.2.1类的重载(属性重载)
class DemoClass(object):
count=0#类属性被重载
def __init__(self,name):#构造方法被重载
self.name=name#实例属性被重载
DemoClass.count+=1
class HumanNameClass(DemoClass):
count = 99#类属性被重载
def __init__(self,name):#构造方法被重载
self.name=name#实例属性被重载
HumanNameClass.count-=1
def printName(self):
return str(HumanNameClass.count)+self.name#类属性用类名调用,不容易被误解
#实例属性用对象名调用,容易被误解
dc1=HumanNameClass("老王")
print(dc1.printName())
3.2.2类的重载(方法重载)
class DemoClass(object):
count=0#类属性被重载
def __init__(self,name):
self.name=name
DemoClass.count+=1
def printCount(self):
return str(DemoClass.count)+self.name
class HumanNameClass(DemoClass):
def __init__(self,name):
self.name=name
def printCount(self):
return super().printCount()+"同志"#增量重载使用super方法
dc1=HumanNameClass("老王")
print(dc1.printCount())
class DemoClass(object):
count=0#类属性被重载
def __init__(self,name):
self.name=name
DemoClass.count+=1
def printCount(self):
return str(DemoClass.count)+self.name
class HumanNameClass(DemoClass):
def __init__(self,name):
self.name=name
def printCount(self):
text=str(DemoClass.count) + self.name+"同志"
return text
dc1=HumanNameClass("老王")
print(dc1.printCount())
3.3类的多继承
class DemoClass:
def __init__(self,name):
self.name=name
def printName(self):
return self.name
class NameClass:
def __init__(self,title):
self.nick=title
def printName(self):
return self.nick+"同志"
class HumanNameClass(DemoClass,NameClass):
pass
# class HumanNameClass(NameClass,DemoClass):
# pass
dc1=HumanNameClass("老王")#多继承,方法printName()按照深度优先,从左至右方式寻找
print(dc1.printName())
class DemoClass:
def __init__(self,name):
self.name=name
def printName(self):
return self.name
class NameClass:
def __init__(self,title):
self.nick=title
def printName(self):
return self.nick+"同志"
class HumanNameClass(DemoClass,NameClass):
def printName(self):
return super().printName()+"你好"#多继承,super()按照深度优先,从左至右方式寻找基类方法
dc1=HumanNameClass("老王")
print(dc1.printName())
4.类的运算
4.1算数运算的重载
class NewList(list):
def __add__(self, other):
result=[]
for i in range(len(self)):
try:
result.append(self[i]+other[i])
except:
result.append(self[i])
return result
ls=NewList([1,2,3,4,5,6])
lt=NewList([1,2,3,4])
print(ls+lt)#对两个对象进行相加运算
4.2比较运算的重载
class NewList(list):
def __lt__(self, other):
#以各元素算数和为比较依据
s,t=0,0
for c in self:
s+=c
for c in other:
t+=c
return True if s<t else False
ls=NewList([6,1,2,3])
lt=NewList([1,2,3,99])
print([6,1,2,3]<[1,2,3,99])
print(ls<lt)
4.3成员运算的重载
class NewList(list):
def __contains__(self, item):
#各元素算数和也作为成员
s=0
for c in self:
s+=c
if super().__contains__(item) or item==s:
return True
else:
return False
ls=NewList([6,1,2,3])
print(6 in ls,12 in ls)
4.4其他运算的重载
class NewList(list):
def __format__(self, format_spec):
#格式化输出,以逗号分隔
t=[]
for c in self:
if type(c)==type("字符串"):
t.append(c)
else:
t.append(str(c))
return ",".join(t)
ls=NewList([1,2,3,4])
print(format([1,2,3,4]))
print(format(ls))
5.类的多态
5.1参数类型的多态
class DemoClass:
def __init__(self,name):
self.name=name
def __id__(self):
return len(self.name)
def lucky(self,salt):
s=0
for c in self.name:
s+=(ord(c)+id(salt))%100
return s
dc1=DemoClass("老王")
dc2=DemoClass("老李")
print(dc1.lucky(10))
print(dc1.lucky("10"))
print(dc1.lucky(dc2))
5.2参数形式的多态
class DemoClass:
def __init__(self,name):
self.name=name
def __id__(self):
return len(self.name)
def lucky(self,salt=0,more=9):
s=0
for c in self.name:
s+=(ord(c)+id(salt)+more)%100
return s
dc1=DemoClass("老王")
print(dc1.lucky())
print(dc1.lucky(10))
print(dc1.lucky(10,100))
6.Python类的高级话题
6.1命名空间的理解
count=0#模块的命名空间
def getConutting(a):
count=0#第一层函数的命名空间
if a!="":
def doCounting():
nonlocal count#第二层函数的命名空间
#nonlocal什么变量不在当前命名空间变量在上层命名空间,但不是全局
count+=1
doCounting()
return count
print(getConutting("1"),count)
print(getConutting("2"),count)
print(getConutting("3"),count)
count=0#模块的命名空间
def getConutting(a):
count=0#第一层函数的命名空间
if a!="":
def doCounting():
global count#第二层函数的命名空间
#global声明变量在全局命名空间
count+=1
doCounting()
return count
print(getConutting("1"),count)
print(getConutting("2"),count)
print(getConutting("3"),count)
6.2类的特性装饰器
#使用@property把类中的方法变成对外可见的“属性”
#@<方法名>.setter用于设定属性的赋值操作
class DemoClass:
def __init__(self,name):
self.name=name
@property#使用@property把类中的方法变成对外可见的“属性”
def age(self):
return self._age
@age.setter#@<方法名>.setter用于设定属性的赋值操作
def age(self,value):
print(value)
if value< 0 or value>100:
value=30
self._age=value
dc1=DemoClass("老李")
dc1.age=-100
print(dc1.age)
class xuehang:
def __init__(self):
pass
@property
def age(self):
return self._ags
@age.setter
def age(self,ages):
if ages>20:
self._ags=10
a=xuehang()
a.age=100
print(a.age)
6.3自定义的异常类型
class DemoException(Exception):
def __init__(self,name,msg="自定义异常"):
self.name=name
self.msg=msg
try:
raise DemoException("脚本错误")
except DemoException as e:
print("{}异常的报警是{}".format(e.name,e.msg))
6.4类的名称修饰
class DemoClass:
def __init__(self,name):
self.name=name
self._nick=name+"同志"#约定内部使用
def getNick(self):
return self._nick
dc1=DemoClass("老李")
print(dc1.getNick())
print(dc1._nick) #外部仍然可以调用
class DemoClass:
def __init__(self,name):
self.name=name
self.nick_=name+"同志"#仅是为了避免重名
def getNick(self):
return self.nick_
dc1=DemoClass("老李")
print(dc1.getNick())
print(dc1.nick_) #外部仍然可以调用
class DemoClass:
def __init__(self,name):
self.name=name
self.__nick=name+"同志"#仅是为了避免重名
def getNick(self):
return self.__nick
dc1=DemoClass("老李")
print(dc1.getNick())
print(dc1._DemoClass__nick)
print(dc1.__nick)
6.5类的最小空类
class DemoClass:
pass
a=DemoClass()