zoukankan      html  css  js  c++  java
  • classmethod,staticmethod,反射,魔法方法,单例模式

    classmethod

    classmethod是一个装饰器,可以装饰给类内部的方法,使该方法绑定给类来使用

    1. 对象绑定方法特殊之处:由对象来调用,会把对象当作第一个参数传给该方法
    2. 类绑定方法特殊之处:由类来调用,会把类当作第一个参数传给该方法
    class People:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        @classmethod
        def tell_info(cls):
            print(cls)
            print('此处是类方法。。。')
    
    
    People.tell_info()
    '''
    <class '__main__.People'>
    此处是类方法。。。
    '''
    

    小练习:

    # settings.py
    '''
    USER = 'tank'
    PWD = '123'
    '''
    
    
    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_auth(cls):
            obj = cls(settings.USER, settings.PWD)
            return obj
    
    
    obj = Teacher.login_auth()
    obj.index()
    

    staticmethod

    staticmethod是一个装饰器,可以装饰给类内部的方法,使得该方法既不绑定类,也不绑定对象

    import settings
    import uuid
    import hashlib
    
    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_auth(cls):
            obj = cls(settings.USER, settings.PWD)
            return obj
    
        @staticmethod
        def create_id():
            uuid_obj = uuid.uuid4()
            md5 = hashlib.md5()
            md5.update(str(uuid_obj).encode('utf-8'))
            return md5.hexdigest()
    
    
    print(Teacher.create_id())
    t1 = Teacher('tank', 123)
    print(t1.create_id()) 
    

    instance

    python内置函数,可以传入两个参数,用于判断参数1是否是参数2的一个实例。

    判断一个对象是否是一个类的实例

    class Foo:
        pass
    
    foo_obj = Foo()
    print(foo_obj)
    print(foo_obj.__class__.__dict__)
    print(foo_obj in Foo.__dict__)   # 判断一个对象是否是类的实例
    
    print(isinstance(foo_obj, Foo))  # 判断一个对象是否是类的实例
    

    issubclass

    python内置函数,可以传入两个参数,用于判断参数1是否是参数2的一个子类

    判断一个类是否是一个类的子类

    class Foo:
        pass
    
    
    class Goo(Foo):
        pass
    
    
    print(issubclass(Goo, Foo))  # True
    

    反射

    指的是通过“字符串”对 对象或类的属性进行操作

    hasatter

    通过字符串,判断字符串是否是对象或类的属性

    class People:
        country = 'China'
    
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    
    p = People('tank', 18, 'male')
    # 普通方式
    print('name' in p.__dict__)
    # hasatter
    print(hasattr(p, 'name'))
    print(hasattr(p, 'country'))
    

    getatter

    通过字符串,获取对象或类的属性4

    # 普通方式
    print(p.__dict__.get('name'))
    # getatter
    print(getattr(p, 'name', 'jason'))
    

    setatter

    通过字符串,设置对象或类的属性

    setattr(p, 'level', '3.0')
    print(hasattr(p, 'level'))
    

    delatter

    通过字符串,删除对象或类的属性

    delattr(p, 'name')
    
    print(hasattr(p, 'name'))
    

    反射小练习

    class Movie:
        def input_cmd(self):
            print('请输入命令......')
            while True:
                cmd = input('请输入执行的命令:').strip()
    
                # 若输入的cmd命令是当前对象的属性
                if hasattr(self, cmd):
                    method = getattr(self, cmd)
                    method()
    
    
        def upload(self):
            print('正在上传...')
    
        def download(self):
            print('正在下载...')
    
    
    obj = Movie()
    obj.input_cmd()
    

    魔法方法

    凡是类内部定义,以__开头,__结尾的方法都称之为魔法方法,又称类的内置方法

    魔法方法会在某些条件成立的时候触发

    __init__:在掉用类时触发
    __str__:在打印对象时触发

    __del__:会在程序结束时触发,销毁对象, 该方法会在最后执行

    __getattr__:会在对象.属性时,属性没有的情况下才会触发

    __setattr__:会在对象.属性 = 属性值的时候触发

    __new__:会在__init__执行前触发
    __call__:会在对象调用时触发

    class Foo:
    
        def __new__(cls, *args, **kwargs):
            print(cls)
            return object.__new__(cls)   # 真正产生一个对象
    
        # 若当前类的__new__没有return一个空对象,则不会触发
        def __init__(self):
            print('在调用类时触发...')
    
        def __str__(self):
            print('在打印对象时触发')
            # 必须要有一个返回值,该返回值必须是字符串
            return '我是Foo实例化出的对象'
    
        def __del__(self):
            print('对象被销毁前执行该程序')
    
        def __getattr__(self, item):
            print('会在对象.属性时,属性没有的情况下才会触发')
            print(item)
            # 若想打印属性的结果,必须要return一个值
    
        # 注意:执行该方法时,外部“对象.属性=属性值”时无效
        def __setattr__(self, key, value):
            print('会在对象.属性 = 属性值的时候触发')
            print(key, value)
            print(self, 111)
            self.__dict__[key] = 1234
    
        def __call__(self, *args, **kwargs):
            print(self)
            print('调用对象时触发')
    
    
    obj = Foo()
    # print(obj)
    # print(obj.x)
    # obj.x = 3
    # print(obj.x)
    #
    # obj()
    
    

    魔法方法del应用:

    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 __del__(self):
            self.f.close()
            print('文件关闭成功')
    
    f = MyFile('settings.py')
    f.file_open()
    f.file_read()
    

    单例模式

    什么是单例

    单例模式指的是单个实例,实例指的是调用类产生的对象

    为什么要使用单例

    实例化多个对象会产生不同的内存地址,单例可以调用者在调用同一个对象时,都指向同一个内存地址。例如打开文件。

    单例的目的:为了减少内存的占用。

    class File:
        def __init__(self, file_name, mode='r', encoding='utf-8'):
            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()
            return res
    
        def close(self):
            self.f.close()
    
    obj1 = File('settings.py')
    obj2 = File('settings.py')
    obj3 = File('settings.py')
    print(obj1)
    print(obj2)
    print(obj3)
    
    '''
    <__main__.File object at 0x00000143ACD7D978>
    <__main__.File object at 0x00000143ACDA20B8>
    <__main__.File object at 0x00000143ACDA2198>
    '''
    

    可以看出,实例化出三个对象,它们的地址都不相同

    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
    
        def __init__(self, file_name, mode='r', encoding='utf-8'):
            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()
            return res
    
        def close(self):
            self.f.close()
    
    obj1 = File.singleton('settings.py')
    obj2 = File.singleton('settings.py')
    obj3 = File.singleton('settings.py')
    print(obj1)
    print(obj2)
    print(obj3)
    '''
    <__main__.File object at 0x000001A04F472198>
    <__main__.File object at 0x000001A04F472198>
    <__main__.File object at 0x000001A04F472198>
    '''
    
    class File:
    
        __instance = None
    
        # 单例模式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='utf-8'):
            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()
            return res
    
        def close(self):
            self.f.close()
    
    obj1 = File('settings.py')
    obj2 = File('settings.py')
    obj3 = File('settings.py')
    print(obj1)
    print(obj2)
    print(obj3)
    '''
    <__main__.File object at 0x00000184C9CD2198>
    <__main__.File object at 0x00000184C9CD2198>
    <__main__.File object at 0x00000184C9CD2198>
    '''
    
  • 相关阅读:
    8皇后问题
    初级8皇后问题
    某个集合的子集问题
    n全排列输出和 n个数的组合(数字范围a~b)
    (转)李明博:我的12年等于24年 快速提升的秘诀是什么 别人以为我早起是先天的,事实靠的是努力 训练,除了反复的努力之外没有什么别的秘诀 像企业主一样去思考,一样查找问题,一同去解决它,并且还要制定出比企业主要求更高的目标。李明博像我一样,不,他比我更把公司当成自己的
    (转)当别人努力的时候,你在做什么? 评论事情的一种态度 当你在抱怨的时候,为什么不想想我做了什么? 把简单的原则坚持贯彻下去 消极的心态,养成了惯性的思维,一切都是不好的。 也许这就是人性的弱点,不经意的习惯,却逐渐腐蚀了你的人生。
    对于保险的看法和如何拒绝保险推销 保险应该主要是有2个主要作用: 1. 分担风险 2. 投资 保险的常用推销方法和该保险的卖点 拒绝保险的方法
    业务、架构、技术,我们应该关注什么 Java和.Net的优势劣势简单看法 市场经济决定,商业之道即是软件之道,市场的需求决定着软件技术的发展 利益决定着选择应用新技术
    我的学习工作经历,一个园林专业中专毕业生的IT之路 学习编程 创业
    “医疗信息化行业之中的联发科”- 我们在医疗行业中的定位及目标 想做一个面对中小企业的专业上游软件供应商 台湾联发科技颠覆掉的是一个封闭的手机产业系统 解决方案,即AgileHIS.NET数字化医院基础方案
  • 原文地址:https://www.cnblogs.com/setcreed/p/11667759.html
Copyright © 2011-2022 走看看