• python之面向对象函数与方法,反射,双下方法


    一、函数和方法

    1.函数和方法的区别

    函数: 全都是显性传参,手动传参,与对象无关

    方法: 存在隐性传参,与对象有关

    1.1通过函数名可以判断

    len()就是函数
    str.count()就是方法
    
    def func():
    	pass
    class A:
    	def func(self):
    
    print(func)
    obj = A()
    print(obj.func()) 
    

    2.2通过types模块判断

    from types import functionType
    from types import MethodType
    print(isinstance(func,FunctionType))
    print(isinstance(func,MethodType))
    
    • 类名调用func就是一个函数
    • 对象调用func就是一个方法

    2.3 对于静态方法的研究

    print(isinstance(A.f, FunctionType)) #指的是函数类型
    print(isinstance(A.f, MethodType)) #类方法
    

    二、反射

    有什么用

    有些时候你明明知道一个变量的字符串数据类型的名字,你想调用它,但是调不到,就可以使用反射

    反射方法

    通过字符串去操作一个对象

    getattr 获取一个属性或者方法
    getattr(obj,'name1',None) #前面是类名,后面是字符串形式的属性或方法
    
    hasattr 判断属性或方法是否存在  
    hasattr(obj,'name')
    
    setattr 设置新的属性
    setattr(obj,'hobby', '玩')
    
    hasattr 删除属性
    hasattr(obj, 'func')
    

    对实例化对象的反射

    前面是实例化对象名,后面是字符串形式的实例化对象的属性

    class Foo:
        f = '类的静态变量'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def say_hi(self):
            print(f'hi,{self.name}')
    
    obj = Foo('egon', 73)
    
    # 检测是否含有某属性 name
    print(hasattr(obj, 'name'))
    print(hasattr(obj, 'say_hi'))
    
    # 获取属性
    n = getattr(obj, 'name')  # 等同于 obj.name
    print(n)
    func = getattr(obj, 'say_hi')
    func()
    
    # print(getattr(obj, 'aaaaaaaa', '不存在啊'))  # 报错
    
    # 设置属性
    setattr(obj, 'sb', True)  # 等同于 obj.sb = True
    setattr(obj, 'show_name', lambda self: self.name + 'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    # 删除属性
    delattr(obj, 'age')  # 等同于 del obj.age
    delattr(obj, 'show_name')
    # delattr(obj, 'show_name111')  # 不存在,则报错
    
    print(obj.__dict__)
    

    对类的反射

    前面是类名,后面是字符串形式的类的属性或方法

    class Foo(object):
        staticField = "old boy"
    
        def __init__(self):
            self.name = 'wupeiqi'
    
        def func(self):
            return 'func'
    
        @staticmethod
        def bar():
            return 'bar'
    
    print(getattr(Foo, 'staticField')) # 前面是类名,后面是类的属性或方法
    print(getattr(Foo, 'func'))
    print(getattr(Foo, 'bar'))
    

    对当前模块的反射

    import sys
    
    def s1():
        print('s1')
    
    def s2():
        print('s2')
    
    this_module = sys.modules[__name__]  # 比较推荐#sys.modules 获得到的是 当前文件的所有属性及方法,返回是一个字典
    # 等同于 this.module = sys.modules["__main__"]
    
    hasattr(this_module, 's1')
    getattr(this_module, 's2')()
    

    对其他模块的反射

    """
    程序目录:
        module_test.py
        index.py
    """
    
    #  module_test.py   中的代码
    def test():
        print('from the test')
    
    # index.py   中的代码
    import module_test as obj
    
    # obj.test()
    
    print(hasattr(obj, 'test'))
    
    getattr(obj, 'test')()
    
    class A:
    
        static_field = '静态属性'
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def func(self):
            print('in A func')
    
    
    obj = A('MC骚Q', 18)
    print(obj.name)
    #
    print(hasattr(obj,'name'))  # ***
    print(getattr(obj,'name1',None))  ***
    setattr(obj,'hobby', '玩') *
    print(getattr(obj,'hobby'))
    print(obj.hobby)
    delattr(obj,'name') *
    print(hasattr(obj,'name'))
    if hasattr(obj, 'static_field'):
        print(getattr(obj,'static_field'))
    
    if hasattr(obj, 'func'):
        # print(getattr(obj,'func'))
        getattr(obj,'func')()
    

    三、双下方法

    __len__

    用途

    ​ 可以获取类中属性个数,如__init__

    格式

    def __len(self):
    	print('触发__len__方法')
    	return 10
    

    触发方法

    len(obj)
    

    一个对象之所以可以使用len()函数,根本原因是你这个对象从输入的类中有__len__方法,方法其实执行的是 len 当类中没有__len__ 这个方法时,使用len()就会报错

    __hash__

    用途

    哈希

    触发方法

    print(hash(obj))
    

    __str__方法

    用途

    ​ 打印输出

    触发方法

    print(obj)
    

    __repr__方法

    用途

    ​ 同__str__一样,与str同时存在的时候,str的优先级要高

    触发方法

    print(此对象是%r那就先执行repr的方法)
    

    __call__方法

    触发方法

    obj() #对象加括号触发就会触发类里面的__call__方法
    

    __eq__方法

    用途

    ​ 当你对一个类中的两个对象比较操作的时候,就会触发__eq__方法

    __del方法

    有什么用

    ​ 对象引用为零的时候, 析构方法,主动删除

    ​ 从内存中删除,垃圾回收机制♻️

    调用方法

    l2 = [1,2,3]
    dic = {1:22, 2:33}
    del l2
    del dic #主动删除
    

    __new__(*****************)

    用什么用

    • 构造一个对象出来(自动执行__init__文件的时候就是__new__在干这件事儿)
    • 创建构建并返回一个新的空间
    class A(object):
    
        def __init__(self):
            print('in __init__')
        def __new__(cls, *args, **kwargs):
            print('in __new__')
            object1 = object.__new__(cls)
            return object1
    obj = A()
    # 输出结果
    in __new__
    in __init__
    

    单例模式

    单例模式单例模式就是一种设计模式,一个类智能实例化一个对象,无论你实例化多少次,内存中都只有一个对象,目的是为节省 空间

    面试几乎都会让你手写一个单例模式

    class A:
        __instance = None
    
        def __new__(cls, *args, **kwargs):
            if not cls.__instance:
                object1 = object.__new__(cls) 
                cls.__instance = object1
            return cls.__instance
    obj = A()
    obj1 = A()
    obj2 = A()
    obj3 = A()
    print(obj, obj1, obj2, obj3)
    

    __item__方法

    用途

    对对象进行类似于字典的操作

    __getitem__、__setitem__、__delitem__、

    class Foo:
        def __init__(self, name):
            self.name = name
    
        def __getitem__(self, item):
            print(item)
            print('get时 执行我')
    
        def __setitem__(self, key, value):
            self.name = value
            print('set时执行我')
    
        def __delitem__(self, key):
            print(f'del obj{[key]}时,我执行')
    
    obj = Foo('御姐')
    # obj.__dict__
    # obj['name']
    # obj['name'] = '萝莉'
    # print(obj.name)
    del obj['name']
    
    class Foo:
        def __init__(self, name, key, value):
            self.name = name
    
            self.dict = {}
            self.dict[key] = value
    
        def __getitem__(self, key):
            print("1313", self.dict[key])
            # return self.dict[key]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
            print(key, "创建新的键值对")
    
        def __delitem__(self, key):
            print('del obj[', key, ']时,我执行')
            self.__dict__.pop(key)
    
        def __delattr__(self, item):
            print('del obj.', item, '时,我执行')
            self.__dict__.pop(item)
    
    f1 = Foo("sb", "A", "1")
    f1["A"]  # 会去执行  __getitem__ 方法
    f1['age'] = 18  # 会去执行  __setitem__ 方法
    f1['age'] = 112  # 修改也会去执行 __setitem__ 方法
    f1['age1'] = 250  # 修改也会去执行 __setitem__ 方法
    del f1.age1  # 会去执行  __delattr__ 方法
    del f1['age']  # 会去执行  __delitem__ 方法
    f1['name'] = 'alex'  # 会去执行  __setitem__ 方法
    print(f1.__dict__)
    
    
    
    

    利用类方法的认证功能***

    class Auth:
    
        function_list = [('login','请登录'),('register','请注册'),('exit_q','退出')]
    
        def login(self):
            print('欢迎登录')
    
        def register(self):
            print('欢迎注册')
    
        def exit_q(self):
            print('退出程序')
            exit()
    
    while 1:
        obj = Auth()
        for num,option in enumerate(obj.function_list,1):
            print(num,option[1])
    
        try:
            choice_num = input('请输入选择: ').strip()
            if hasattr(obj,obj.function_list[int(choice_num)-1][0]):
                getattr(obj,obj.function_list[int(choice_num)-1][0])()
        except IndexError:
            print('请输入超过范围')
        except ValueError:
            print('请输入数字')
    
  • 相关阅读:
    Centos7创建systemctl服务
    in a frame because it set 'X-Frame-Options' to 'sameorigin'
    systemd-journald服务占用CPU过高
    Centos7修改了最大文件打开数不生效
    Docker部署Redis主从和哨兵
    基于Vue的前端项目访问首页刷新后报404
    npm的.npmrc文件在哪里?缓存及全局包文件在什么位置?
    react native 淘宝镜像
    react native 示例代码
    iOS9 & iOS10 & iOS11 HTTP 不能正常使用的解决办法
  • 原文地址:https://www.cnblogs.com/zanao/p/11227589.html
Copyright © 2020-2023  润新知