函数与方法,反射,双下方法

1.函数与方法
1.通过函数名可以大致判断
def func():
    pass
class A:
    def func(self):
        pass
print(func)  # <function func at 0x00000000005D1EA0>
obj = A()
print(obj.func)  # <bound method A.func of <__main__.A object at 0x0000000001DE1CF8>>
2.通过types模块去验证
from types import FunctionType
from types import MethodType
def func():
    pass
class A:
    def func(self):
        pass
    @classmethod
    def func1(cls):
        pass
    @staticmethod
    def func2():
        pass

print(isinstance(func, FunctionType))   T
print(isinstance(func, MethodType))     F
# 类名调用func 就是一个函数
print(isinstance(A.func, FunctionType))  T
print(isinstance(A.func, MethodType))    F
# 对象调用func 就是一个方法
obj = A()
print(isinstance(obj.func, FunctionType)) F
print(isinstance(obj.func, MethodType))   T
# 类方法  类、方法调用都是方法
print(isinstance(A.func1, MethodType))    T
print(isinstance(obj.func1, MethodType))  T
# 静态方法  类、方法调用都是函数
print(isinstance(A.func2, FunctionType))   T
print(isinstance(obj.func2, FunctionType)) T
函数:全是显性传参
方法:存在隐性传参
2.反射
从实例的角度去研究反射
class A:
    static_field = '静态属性'
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def func(self):
        print('in A func')
obj = A('蔡徐坤', 21)    
print(hasattr(obj,'name'))     判断
print(getattr(obj,'name',None))   查
setattr(obj,'hobby', '玩')      增、改
print(getattr(obj,'hobby'))     
delattr(obj,'name')            删
print(hasattr(obj,'name')) 
从类的角度研究反射
class A:
    static_field = '静态属性'
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def func(self):
        print('in A func')
obj = A('蔡徐坤', 21)
print(getattr(A, 'func'))
getattr(A,'func')(obj)
从当前脚本研究反射
def func1():
    print('in func1')
def func2():
    print('in func2')
def func3():
    print('in func3')

l1 = [func1, func2, func3]
l1 = [f'func{i}' for i in range(1,4)]
import sys
this_modules = sys.modules[__name__]  # 获取当前脚本这个对象
for i in l1:
    getattr(this_modules, i)()
    
class Auth:
    function_list = [('login','请登录'), ('register','请注册'), ('exit', '退出')]
    def login(self):
        print('登录函数')
    def register(self):
        print('注册函数')
    def exit(self):
        print('退出...')
while 1:
    obj = Auth()
    for num,option in enumerate(obj.function_list,1):
        print(num,option[1])
    choice_num = input('请输入选择:').strip()
    if hasattr(obj,choice_num):
        getattr(obj,choice_num)()
3.python中特殊的双下方法
1.__len__
class A:
    def __init__(self,name,age,hobby):
        self.name = name
        self.age = age
        self.hobby = hobby
    def __len__(self):
        # print('触发__len__方法')
        return len(self.__dict__)
一个对象之所以可以使用len()函数,根本原因是这个对象从属于的类中有__len__方法
2.__hash__
class A(object):
    pass
obj=A()
print(hash(obj))  调用obj这个对象的类(基类的)__hash__方法
3.__str__  __repr__
class Student:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
    def __repr__(self):
        return f'姓名:{self.name}年龄:{self.age}性别:{self.sex}'
    def __str__(self):
        return (f'姓名:{self.name}年龄:{self.age}性别:{self.sex}666')
obj = Student('蔡徐坤', 21, '男')
print(obj.__str__())
print(str(obj))
print(repr(obj))
print(obj)  # 先触发__str__方法
4.__eq__
class A:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __eq__(self,obj):
        print('执行eq')
        return True
a = A()
b = A()
print(a == b)  # 对一个类的两个对象进行比较操作,就会触发__eq__方法
5.__del__
class A(object):
    def __del__(self):
        print('执行del')
obj = A()
del obj
6.__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()  # 先触发__new__并且将类名自动传给cls
print(obj)
# 单例模式:一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象
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()
print(obj,obj1,obj2)
7.__item__:对对象进行类似于字典的操作
class Foo:
    def __getitem__(self, key):
        print(key)
        print('get时执行我')
    def __setitem__(self, key, value):
        self.name = value
        print('set时执行我')
    def __delitem__(self, key):
        print(f'del obj{[key]}时,我执行')
obj = Foo()
obj['a']
obj['a'] = '蔡徐坤'
print(obj.name)
del obj['n']
8.__enter__ __exit__
class A:
    def __init__(self,name):
        self.name = name
    def __enter__(self):
        print(111)
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(222)
# 对一个对象类似于进行with语句上下文管理的操作, 必须要在类中定义__enter__ __exit__
with A('mc小龙') as obj:
    print(555)
class A:
    def __init__(self, text):
        self.text = text
    def __enter__(self):  # 开启上下文管理器对象时触发此方法
        self.text = self.text + '您来啦'
        return self  # 将实例化的对象返回f1
    def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
        self.text = self.text + '这就走啦'
with A('大爷') as f1:
    print(f1.text)
print(f1.text)

转载于:https://www.cnblogs.com/wxl1025/p/11180711.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值