day 22 小结

classmethod和staticmethod

​ 翻译: 一个类的方法

​ 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)

原文地址:https://www.cnblogs.com/LZF-190903/p/11661976.html