一,访问限制
原因:直接操作对象属性有两个缺点:无法保证数据安全性,无法进行参数校验。
示例:
class fruit(object): #定义一个类
def __init__(self,name): #定义属性name
self.name=name
f1=fruit('apple') #实例化一个对象,name=apple
f2=fruit(123) #实例化一个对象,name=123,原则上,希望name是一个字符串类型,可是,无法进行参数验证
print(f1.name) #apple
print(f2.name) #123
f1.name='banana' #可以直接对属性进行修改
print(f1.name) #banana
解决方案:
针对无法保证数据安全性:私有属性。
在属性前面加上两个下划线__,就会变成私有属性。私有属性从外部不可访问。
class fruit(object): #定义一个类
def __init__(self,name):
self.__name=name #定义属性name
针对无法进行参数校验:为属性增加get,set方法。虽然看似繁琐,但可以增加参数校验。
class fruit(object): #定义一个类
def __init__(self,name): #定义属性name
self.__name=name
def set_name(self,name):
if isinstance(name,str): #判断接收的参数是str类型
self.__name=name
else:
raise ValueError('name must be str')
def get_name(self):
return self.__name
二,__slots__和property
__slots__
用途:限制实例具有哪些属性。
方法:__slots__=[]
场景:需要对实例的属性加以限制。
作用范围:如果子类中未定义__slots__变量,则对子类毫无影响,如果子类中定义了该变量,则子类中允许的属性为子类和父类__slots__的集合。
property
用途:将类方法变成属性。类方法获取或修改属性太过繁琐,将方法变成属性,可以直接获取到。
方法:@property方法装饰属性的get方法,属性,setter装饰器装饰set方法。
示例:
class fruit(object): #定义一个类
def __init__(self,name): #定义属性name
self.__name=name
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
if isinstance(name,str):
self.__name=name
else:
raise ValueError('name must be str')
三,获取对象信息
type() 判断对象类型
types类中的常量可以判断是否为函数等。
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
isinstance() 判断对象是否为某种类型,或在该类型的父继承链上。
dir() 列出对象的所有属性及方法。
四,类属性和实例属性
实例属性,指实例化后的对象可以具有的属性。
类属性,是指该类所具有的属性。(所有对象均可访问)
警告:类属性和实例属性名最好有所区分。
示例:
class fruit(object): #定义一个类
atest='this is a test'
def __init__(self,name): #定义属性name
self.__name=name