day 22 小结 classmethod和staticmethod isinstance和issubclass 反射 魔法方法(类的内置方法) 单例模式
翻译: 一个类的方法
classmethod是一个装饰器,可以给类内部的方法,使该方法绑定给类来使用
-
对象的绑定方法特殊之处
由对象来调用,会将对象当作第一个参数传给该方法
-
类的绑定方法特殊之处
由类来调用,会将类当作第一个参数传给该方法
class People: def __init__(self,name,age): self.name = name self.age = age @classsmethod def tell_info(cls): # cls==people print(cls) print('此处是类方法...') pass
staticmethod是一个装饰器,可以装饰给类内部的方法,使该方法既不绑定给类也不绑定给对象,也不绑定为类
# settings代码
'''
USER = 'tank'
PWD = '123'
'''
import hashlib
import uuid # 是一个加密模块,uuid4通过时间戳生成时间上唯一的字符串
import settings
class Teacher
def __init__(self,user,pwd):
self.user = user
self.pwd = pwd
def index(self):
if self.user == 'tank' and self.pwd == '123'
print('验证通过,显示主页...')
@classmethod
def login_zuth_from_settings(cls):
obj = cls(settings.USER,settings.PWD)
return obj # Teacher() ---> return = obj
@staticmethod
def create_id()
#生成一个唯一的id字符串
uuid_obj = uuid.uuid4()
md5 = hashlib.md5()
md5.update(str(uuid_obj).encode('utf8'))
return md5.hexdigest()
# obj = Teacher.login_auth_from_settings()
# obj.index()
tea1 = Teacher('tank','123')
tea1.index()
if __name__ == '__main__'
print(type(uuid.uuid4()))
print(Teacher.create_id())
tea1 = Teacher('tank','123')
print(tea1.create_id())
isinstance和issubclass
_class_:获取当前类
isinstance(参数1, 参数2):
python内置的函数,可以传入两个参数,用来判断参数一是否是参数二的一个实例
判断一个对象是否是一个类的实例
issubclass(参数1, 参数2):
python内置的函数,可以传入两个参数,用于判断参数1是否是参数2的子类
判断一个类是否是另一个类的子类
class Foo:
pass
class Goo(Foo):
pass
foo_obj = Foo()
print(isinstance(foo_obj,Foo))
print(isinstance(foo_obj,Goo))
print(issubclass(Goo,Foo))
反射
指的是通过字符串对对象或类的属性进行操作.
hasattr
通过字符串,判断该字符串是否是对象或类的属性
getattr
通过字符串,获取对象或类的属性
setattr
通过字符串,设置对象或类的属性
delattr
通过字符串,删除对象或类的属性
class People:
country = 'China'
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
# 普通方式
p = People('tank',17,'male')
print('name' in p.__dict__)
print('country' in Prople.__dict__)
# hasattr
print(hasattr(p,'name'))
print(hasattr(People,'country'))
# 普通方式
p = People('tank',17,'male')
print(p.__dict__.get('name'))
print(p.__dict__.get('level','9'))
# getattr
print(getattr(p,'name','jason_sb'))
print(getattr(p,'name1','jason_sb'))
print(getattr(People,'country2',China))
# setattr
# 普通
p.leve = 10
print(p.level)
# 反射
setattr(p,'sal','3.0')
print(hasattr(p,'sal'))
# delattr
# 普通
del p.level
print(hasattr(p,'level'))
# 反射
delattr(p,'sal')
print(hasattr(p,'sal'))
反射小练习
class Movie:
def input_cmd(self):
print('输入命令:')
while True:
cmd = input('请输入执行的方法名:').strip()
# 若用户输入的cmd命令是当前对象的属性
if hasattr(self, cmd):
method = getattr(self, cmd)
method()
else:
print('命令错误,请重新输入!')
def upload(self):
print('电影开始上传...')
def download(self):
print('电影开始下载...')
movie_obj = Movie()
movie_obj.input_cmd()
魔法方法(类的内置方法)
凡是在类内部定义,以"__开头__结尾" 的方法都称为魔法方法
魔法方法会在某些条件成立时触发
_init_: 在调用类时触发
_str_: 会在打印时触发
_del_: 会在程序执行结束时触发,对象销毁
_getattr_: 会在对象. 属性时,属性没有才触发
_setattr_: 会在对象. 属性 = 属性值 的时候触发
_call_: 会在对象被调用时触发
__new__: 会在__init__执行前触发
class Foo(object):
def __new__(cls, *args, **kwargs):
print(cls)
return object.__new__(cls) # 真正产生一个空对象
# 若当前类的__new__没有return一个空对象时,则不会触发。
def __init__(self):
print('在调用类时触发...')
# def __str__(self):
# print('会在打印对象时触发...')
# # 必须要有一个返回值, 该返回值必须时字符串类型
# return '[1, 2, 3]'
def __del__(self):
print('对象被销毁前执行该方法...')
def __getattr__(self, item):
print('会在对象.属性时,“属性没有”的情况下才会触发...')
print(item)
# 默认返回None, 若想打印属性的结果,必须return一个值
return 111
# 注意: 执行该方法时,外部“对象.属性=属性值”时无效。
def __setattr__(self, key, value):
print('会在 “对象.属性 = 属性值” 时触发...')
print(key, value)
print(type(self))
print(self, 111)
self.__dict__[key] = value
def __call__(self, *args, **kwargs):
print(self)
print('调用对象时触发该方法...')
foo_obj = Foo()
print(foo_obj)
print(foo_obj.x)
print(foo_obj.x)
foo_obj.x = 123
print(foo_obj.x)
foo_obj()
list1 = [1, 2, 3] # list1 = list([1, 2, 3])
print(list1) # [1, 2, 3]
class MyFile(object):
def __init__(self, file_name, mode='r', encoding='utf-8'):
self.file_name = file_name
self.mode = mode
self.encoding = encoding
def file_open(self):
self.f = open(self.file_name, self.mode, encoding=self.encoding)
def file_read(self):
res = self.f.read()
print(f'''
当前文件名称: {self.file_name}
当前文件数据: {res}
''')
# def close(self):
# self.f.close()
def __del__(self):
self.f.close()
print('文件关闭成功!')
f = MyFile('jason雨后的小故事.txt')
f.file_open()
f.file_read()
print('程序结束,对象被销毁!')
单例模式
单例模式指的是单个实例,实例指的是调用类产生的对象
实例化多个对象会产生不同的内存地址,单例可以让所有调用者,在调用类产生对象的情况下都指向同一份内存地址
单例的目的:减少内存占用
class File:
__instance = None
# 单例方式1:
@classmethod
def singleton(cls,file_name):
if not cls.instance
obj = cls(file_name)
cls.__instance = obj
return cls.instance
# 单例方式2:
def __new__(cls,*args,**kwargs):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
def __init__(self,file_name,mode='r',encoding='utf8')
self.file_name = file_name
self.mode = mode
self.encoding = encoding
def open(self):
self.f = open(self.file_name,self.mode,encoding=self.encoding)
def read(self):
res = self.f.read()
print(res)
def close(self):
self.f.close
# 方式1:
# obj1 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
# obj2 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
# obj3 = File.singleton('jason雨后的小故事.txt') # singleton(cls)
obj1 = File('jason雨后的小故事.txt')
obj2 = File('jason雨后的小故事.txt')
obj3 = File('jason雨后的小故事.txt')
print(obj1)
print(obj2)
print(obj3)
# 方式2:
# obj1 = File('jason雨后的小故事.txt') # singleton(cls)
# obj2 = File('jason雨后的小故事.txt') # singleton(cls)
# obj3 = File('jason雨后的小故事.txt') # singleton(cls)
# print(obj1)
# print(obj2)
# print(obj3)