• Python3 面向对象进阶2


    Classmethod

    • classmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法绑定给类来使用
    • 对象绑定方法的特殊之处: 由对象调用, 将对象作为第一参数传给该方法
    • 类的绑定方法的特殊之处: 由类来调用, 将类作为第一参数传给该方法

    Staticmethod

    • staticmethod是一个装饰器, 用来装饰类内部的方法, 使得该方法既不绑定给对象, 也不绑定给类
    # settings.py
    USER = 'bigb'
    PASSWORD = '123'
    
    
    import uuid
    import settings
    import hashlib
    
    class User:
        def __init__(self, username, password):
            self.username = username
            self.password = password
    
        def admin(self):
            if not self.username == 'bigb' and self.password == '123':
                print('请用管理员账户登录...')
                return
    
            print('显示管理员功能...')
    
        @classmethod
        def __from_settings(cls):
            obj = cls(settings.USER, settings.PASSWORD)
            return obj
    
    
        @staticmethod
        def creat_id():
            uuid_obj = uuid.uuid4()
            md5 = hashlib.md5()
            md5.update(str(uuid_obj).encode('utf-8'))
            return md5.hexdigest()
    
    
    obj1 = User._User__from_settings()
    obj1.admin()  # 显示管理员功能...
    
    
    obj2 = User('blake', '123')
    obj2.admin()  # 请用管理员账户登录...
    
    print(obj2.creat_id())  # e249b25cdd1963a4949cc99d3ad46ff2
    
    

    Isinstance

    • isinstance(args1, args2) Python内置函数, 用于判断args1(对象)是否是args2(类)的一个实例
    class Foo:
        pass
    
    
    foo_obj = Foo()
    
    print(isinstance(foo_obj, Foo))  # True
    

    Issubclass

    • issubclass(args1, args2) Python内置函数, 用于判断args1是否是args2的子类
    class ParentClass:
        pass
    
    
    class ChildClass(ParentClass):
        pass
    
    
    class OtherClass:
        pass
    
    
    print(issubclass(ChildClass, ParentClass))  # True
    print(issubclass(OtherClass, ParentClass))  # False
    
    

    反射

    概念

    • 反射指的是通过字符串对象或类的属性进行操作

    hasattr

    • hasattr(o, attrname) 判断 o(类或对象) 中是否有名字叫 attrname (字符串) 这样的一个属性
    class Chinese:
        country = 'China'
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
    
    people = Chinese('bigb', '18', 'male')
    
    print('name' in people.__dict__)  # True
    print(hasattr(people, 'name'))  # True
    
    

    getattr

    • getattr(o, attrname, default): 用来获取 o(对象或类) 中名叫 attrname(字符串) 的属性对象, 如果没有则返回默认值default
    class Chinese:
        country = 'China'
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_slogan(self):
            print('One China')
    
    
    people = Chinese('bigb', '18', 'male')
    
    people.say_slogan()  # One China
    getattr(people, 'say_slogan')()  # One China
    print(getattr(people, 'country'))  # China
    print(getattr(people, 'country1', 'China'))  # China
    
    
    class Movie:
        def input_cmd(self):
            while True:
                cmd = input('请输入方法名: ')
    
                if hasattr(self, cmd):
                    method = getattr(self, cmd)
                    method()
    
        def upload(self):
            print('电影开始上传...')
    
        def download(self):
            print('电影开始下载...')
    
    
    movie_obj = Movie()
    movie_obj.input_cmd()
    

    setattr

    • setattr(o, attrname, value) 用来添加或修改 o(对象或类) 的属性: attrname = value
    class Chinese:
        country = 'China'
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_slogan(self):
            print('One China')
    
    
    people = Chinese('bigb', '18', 'male')
    
    # 修改
    setattr(people, 'gender', 'female')
    # 添加
    setattr(people, 'province', 'Anhui')
    
    print(people.gender)  # female
    print(people.province)  # Anhui
    
    

    delattr

    • delattr(o, attrname) 用来删除 o(对象或类) 中叫做 attrname(字符串) 的属性
    class Chinese:
        country = 'China'
    
        def __init__(self, name, age, gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def say_slogan(self):
            print('One China')
    
    
    people = Chinese('bigb', '18', 'male')
    
    # 添加
    setattr(people, 'province', 'Anhui')
    
    # 删除
    delattr(people, 'province')
    
    print(people.province)  # AttributeError: 'Chinese' object has no attribute 'province'
    
    
    

    魔法方法

    概念

    • 在类内部定义, 以__开头__结尾的方法的方法都称之为魔法方法, 又称为类的内置方法
    • 魔法方法会在某些条件成立是触发
    • 魔法方法都是object类内定义的方法

    __new__

    • 在调用类时自动触发 (return self__init__)
    class Foo(object):
    
        def __new__(cls, *args, **kwargs):
            print('__new__')
            return object.__new__(cls)  # 产生了一个空对象
    
        def __init__(self):
            print('__init__')
    
    
    foo_obj = Foo()
    
    '''
    __new__
    __init__
    '''
    

    __init__

    • 在创建完对象后自动触发
    • __init__是实例化对象后触发的第一个方法(接收 __new__ return 的 self)

    __str__

    • 在打印对象时自动触发
    • 必须要有一个返回值, 该返回值必须是字符串类型
    class Foo(object):
    
        def __str__(self):
            print('__str__在打印对象时自动触发')
            return '__str__的返回值'
    
    
    foo_obj = Foo()
    print(foo_obj)
    
    '''
    __str__在打印对象时自动触发
    __str__的返回值
    '''
    
    

    __call__

    • 在对象被调用时自动触发
    class Foo(object):
    
        def __call__(self, *args, **kwargs):
            print('__call__在对象被调用时自动触发')
    
    
    foo_obj()  # __call__在对象被调用时自动触发
    

    __getattr__

    • 对象.属性时, 没有该属性时候自动触发
    class Foo(object):
    
        # 默认返回None
        def __getattr__(self, item):
            print('__getattr__会在对象.属性,且属性不存在时自动触发')
            return item
    
    
    foo_obj = Foo()
    print(foo_obj.x)
    
    '''
    __getattr__会在对象.属性,且属性不存在时自动触发
    x
    '''
    

    __setattr__

    • 对象.属性=属性值 时自动触发
    class Foo(object):
    
        def __setattr__(self, key, value):
            print('__setattr__在 对象.属性=属性值 时自动触发')
            print(key, value)
    
    
    foo_obj = Foo()
    
    # 类中有__setattr__ 方法时, 如下操作只触发了__setattr__方法, 并不会给对象添加或修改属性
    foo_obj.x = 1
    
    '''
    __setattr__在 对象.属性=属性值 时自动触发
    x 1
    '''
    
    print(foo_obj.x)  # AttributeError: 'Foo' object has no attribute 'x'
    

    __del__

    • 在对象被销毁后自动触发
    class Foo(object):
    
        def __del__(self):
            print('__del__在对象被销毁后自动触发')
    
    
    foo_obj = Foo()
    
    print('对象被销毁前')
    del foo_obj
    
    print('程序最后的代码.')
    
    '''
    对象被销毁前
    __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):
            data = self.f.read()
            print(f'''
            当前文件: {self.file_name}
            当前文件数据: {data}
            ''')
    
        def __del__(self):
            self.f.close()
            print('关闭文件成功!')
    
    
    f = Myfile('test_file.txt')
    f.file_open()
    f.file_read()
    
    '''
            当前文件: test_file.txt
            当前文件数据: This is the content of test_file.txt
            
    关闭文件成功!
    '''
    

    单例模式

    概念

    • 单例模式指的是某个类在整个系统中只存在一个实例的一种设计模式

    目的

    • 减少内存占用
    • 加快运行性能 (只初始化一次)

    实现方式

    class File(object):
        __instance = None
    
    
        # # 方式1, 通过类的绑定方法实现
        # @classmethod
        # def singleton(cls, file_name):
        #     # 当类没有实例时
        #     if not cls.__instance:
        #         # 创建实例
        #         cls.__instance = cls(file_name)
        #     return cls.__instance
    
    
    
        # 方式2, 通过__new__方法实现
        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 file_read(self):
            data = self.f.read()
            print(f'''
              当前文件: {self.file_name}
              当前文件数据: {data}
              ''')
    
        def close(self):
            self.f.close()
    
    # obj1 = File.singleton('test_file.txt')
    # obj2 = File.singleton('test_file.txt')
    # obj3 = File.singleton('test_file.txt')
    
    obj1 = File('test_file.txt')
    obj2 = File('test_file.txt')
    obj3 = File('test_file.txt')
    
    print(obj1)
    print(obj2)
    print(obj3)
    
    '''
    <__main__.File object at 0x0000000009F87A58>
    <__main__.File object at 0x0000000009F87A58>
    <__main__.File object at 0x0000000009F87A58>
    '''
    
    
  • 相关阅读:
    移动web图片高度自适应的解决方案
    高性能滚动 scroll 及页面渲染优化
    Web学习之跨域问题及解决方案
    apply和call用法
    ES6学习之箭头函数
    JS 对象封装的常用方式
    为Array对象添加一个去除重复项的方法
    最全的常用正则表达式大全
    前端如何实现图片懒加载(lazyload) 提高用户体验
    菜鸟教程 Missing parentheses in call to 'print'
  • 原文地址:https://www.cnblogs.com/bigb/p/11663459.html
Copyright © 2020-2023  润新知