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)