1. 类的实例方法:让对象具有能动性,和实例属性一样,必须进行类实例化之后,才能调用它们;
(1) 类的方法的定义:def fun_name(self,..) pass
其中参数self 代表类的实例,在调用方法时由系统自动提供,方法定义时必须指明self参数;
(2) 类的方法的调用:与普通的函数调用类似;
在类的内部调用:self.<方法名>(参数列表);
在类的外部调用:<实例名>.<方法名>(参数列表);
注:以上两种调用方法中,提供的参数列表中都不需要包括self。
(3) 类内方法相互调用:在一个类的内部方法之间是可以相互调用的,调用方法同上面所述的在类的内部调用方法;
(4) 构造方法及其作用:构造方法就是__init__()方法;
构造方法的作用是在类实例化时初始化实例;注意其方法名是固定的,但其参数同普通方法一样,至少应带有self参数;
构造方法可以带有除self外的其它各种参数(关键字参数、默认参数、用元组收集参数、用字典收集关键字参数等),可以达到在实例化类时,为相应的属性传入指定的值。
练习题目:修改上次定义一个类Box, 要求其具有:访问私有属性(体积)的方法;添加打开(box)方法,并且限制box打开之后,再次调用打开方法会给予提示;
class BoxCount():
"""使用超类作为专门计数的类,计数的属性为类属性"""
count=0
class Box(BoxCount):
"""子类初始化时使超类的属性增加1即可"""
def __init__(self,length,width,height):
self.length=length
self.width=width
self.height=height
self.__volume=length*width*height
self.open=0
self.close=0
BoxCount.count+=1
def access_volume(self):
print("volume",self.__volume)
def open_box(self):
self.open +=1
if (self.open >1):
print(self.open,"warning")
a=Box(1,2,3)
print(BoxCount.count)
b=Box(2,2,2)
print(BoxCount.count)
b.access_volume()
b.open_box()
b.open_box()
print(getattr(a,'length'))
2. 类属性:
(1) 同名的类属性和实例属性:以实例名.属性名引用时,优先引用实例属性;以类名.属性名引用时,只能引用类属性;
(2) 属性访问的特殊方法(反射):反射—提供用字符串来操作类的属性和方法的方式;
主要的工具函数:
hasattr(obj_name, ‘属性名)--判断是否有这个属性 ;
getattr(obj_name, ‘属性名)—获取 ;
setattr(obj_name, ‘属性名, 值) –设置;
delattr(obj_name, ‘属性名)—删除 ;
(3) 属性包装:将方法包装成属性,以隐藏相关实现;目的是控制属性的类型或范围,虚拟属性;
三种属性操作:可读: @property,可写: @<property-name>. setter,可删:@<property-name>.deleter
(4) 描述符:将实现特殊协议方法的类作为另一个类的类属性用来拦截喝控制属性访问并可以重复使用;
协议方法:__get__(); __set__(); __delete__();
描述符的分类:数据描述符(实现三个全部协议方法),非数据描述符(实现部分协议方法);
说明:所有类成员函数都是非数据描述符,比如含有__get__()方法。只能在新式类中使用;
描述符的例子:
class NonNeg:
def __init__(self,default=0):
self.default=default
def __get_(self,instance,owner):
return self.default
def __set__(self,instance,val):
if val>0:
self.default=val
else:
print("This value must be NonNegative")
def __delete__(self,instance):
pass
class Movie:
rating=NonNeg()
score=NonNeg()
if __name__=="__main__":
m=Movie()
print("rating",m.rating.default)
print("score",m.score.default)
m.rating=80
print("rating",m.rating.default)
m.score=-2
print("score",m.score.default)
(5) __call__() 让类的实例如函数一样可调用;例子如下:
class Best:
def __call__(self):
print("call")
t=Best()
t() #实现类的实例可以如函数一样调用
练习题目:使用属性包装器将私有属性__color包装为color(可读写)属性;为其定义__call__(),当作为函数调节时,返回其体积;
# -*- coding: utf-8 -*-
"""
Created on Sat Apr 11 12:27:12 2020
@author: Cool Girl
"""
class BoxCount():
"""使用超类作为专门计数的类,计数的属性为类属性"""
count=0
class Box(BoxCount):
"""子类初始化时使超类的属性增加1即可"""
def __init__(self,length,width,height,color="red"):
self.length=length
self.width=width
self.height=height
self.__volume=length*width*height
BoxCount.count+=1
self.__color=color
@property #可读
def color(self):
return self.__color
@color.setter #可写
def color(self,color):
if (color=="red"):
print("Ok")
else:
self.__color=color
print("Fail")
def __call__(self):
return self.__volume
a=Box(1,2,1)
print(BoxCount.count)
b=Box(2,2,11,"red")
print(BoxCount.count)
a.color="red"
b.color="blue"
b.color
print(a.color, b.color)
print(b())