类的私有化
class People:
_country='China'#私有属性,仍然可以通过._country访问
__language='Chinese'#私有属性,不可以通过.__language访问,可以通过_People__language访问
def __init__(self,name,age,gender):
self.name=name
self._gender=gender
self.__age=age
def _test(self):
print('this is test')
def __test(self):
print('this is test2')
print(People.__dict__)#可以看到python对类的双下划线私有属性和方法进行了重命名
print(People._country)
#print(People.__language)会报错
print(People._People__language)
p=People('Alex',18,'Male')
print(p.__dict__)#可以看到python对实例的双下划线私有属性和方法进行了重命名
print(p.name,p._gender,p._People__age)
p._test()
p._People__test()
虽然私有变量与方法都可以通过一定方式访问到,但是不推荐去访问这些值
反射
class People:
_country='China'#私有属性,仍然可以通过._country访问
__language='Chinese'#私有属性,不可以通过.__language访问,可以通过_People__language访问
def __init__(self,name,age,gender):
self.name=name
self._gender=gender
self.__age=age
def _test(self):
print('this is test')
def __test(self):
print('this is test2')
p=People('Alex',18,'Male')
#查看类或者实例是否有给定的属性或者方法,返回True或者False
print(hasattr(People,'_test'))
print(hasattr(p,'__age'))
#获取类或实例的属性或者方法的值,当属性或方法不存在时,返回输入的第三参数,默认是None
print(getattr(People,'_country'))
print(getattr(p,'__age',0))
#给类或实例添加属性或者方法
setattr(People,'func',lambda x:x+1)
print(People.func(10))
setattr(People,'Skin','Yello')
print(People.Skin)
setattr(p,'Salary',10000)
print(p.Salary)
print(People.__dict__)
print(p.__dict__)
#删除类或实例的属性或者方法
delattr(p,'Salary')
delattr(People,'_test')
print('-'*20)
print(People.__dict__)
print(p.__dict__)
类内置的attr属性
其实反射中的四种方法是调用类内置的attr方法。例如调用getattr()其实在调用类中内置的__getattr__().
调用getattr(obj,name)若name属性已存在则不会调用__getattr__方法,当输入的属性不存在时才会调用.通过自定义__getattr__函数可以说明
def __init__(self,name,age,gender):
self.name=name
self._gender=gender
self.__age=age
def _test(self):
print('this is test')
def __test(self):
print('this is test2')
def __getattr__(self, item):
print('执行__getattr__,属性%s不存在'%item)
p=People('Alex',18,'ale')
p.name
p.age
调用setattr()时立即调用__setattr__函数,特别是实例化时其实就是调用__setattr__
class People:
_country='China'#私有属性,仍然可以通过._country访问
__language='Chinese'#私有属性,不可以通过.__language访问,可以通过_People__language访问
def __init__(self,name,age,gender):
self.name=name
self._gender=gender
self.__age=age
def _test(self):
print('this is test')
def __test(self):
print('this is test2')
def __getattr__(self, item):
print('执行__getattr__,属性%s不存在'%item)
def __setattr__(self, key, value):
print('设置属性%s:%s'%(key,value))
p=People('Alex',18,'ale')
p.name#其实并没有设置,只是打印出来了,所以属性不存在
p.age
调用hasattr(),delattr()时一样会立即执行__hasattr__,__delattr__函数
__getattr__的使用
import time
class FileHandler:
def __init__(self,filename,model='w+',encoding='utf-8'):
self.file=open(filename,model,encoding=encoding)
self.model=model
self.encoding=encoding
def write(self,line):
if self.model=='r':
print('请转换到写入模式')
elif not isinstance(line,str):
print('请输入字符串')
else:
line=time.strftime('%Y-%m-%d %X')+' '+line
self.file.write(line)
def __getattr__(self, item):
return getattr(self.file,item)
f1=FileHandler('a.txt','a')
f1.write(123456)
f1.write('123456\n')
time.sleep(1)
f1.write('hello world\n')
time.sleep(1)
f1.write('111111')
f1.writelines(['人生苦短',',','我用Python'])
# print(f1.read())