Descriptor描述器 & 类初始化参数检查
- 实现StaticMethod,完成staticmethod装饰器功能
- 实现ClassMethod,完成classmethod装饰器功能
class StaticMethod:
def __init__(self,fn):
print('StaticMethod Init')
self.fn=fn
def __get__(self,instance,owner):
print('StaticMethod.__get__',self,instance,owner)
return self # 返回self.fn 或者使用__call__变成可调用对象
def __call__(self,*args,**kwargs):
return self.fn(*args,**kwargs)
from functools import partial
class ClassMethod:
def __init__(self,fn):
print('ClassMethod Init')
self.fn=fn
def __get__(self,instance,owner):
print('ClassMethod.__get__',self,instance,owner)
def f(*args,**kwargs):
ret=self.fn(owner,*args,**kwargs)
return ret
return partial(self.fn,owner)
class B:
@StaticMethod
def ore(*args,**kwargs): # ore=StaticMethod(ore)
print('ore',args,kwargs)
@ClassMethod
def rag(cls,*args,**kwargs): # rag=ClassMethod(rag)
print(cls,args,kwargs)
print(B.ore)
B.ore(23423)
print('$'*80)
print(B.rag)
print(B.rag(234234))
class ClassMethod: def __init__(self, fn): self.fn = fn def __get__(self, instance, owner): return lambda *args, **kwargs: self.fn(owner, *args, **kwargs)
class StaticMethod:
def __init__(self,fn):
self._fn=fn
def __get__(self,instance,owner):
return self._fn
class B:
@StaticMethod
def ore(): # ore=StaticMethod(ore)
print('static method')
B.ore()
B().ore()
from functools import partial
class ClassMethod:
def __init__(self,fn):
self._fn=fn
def __get__(self,instance,owner):
return partial(self._fn,owner)
class B:
@ClassMethod
def ore(cls):
print(cls.__name__)
print(B.__dict__)
print(B.ore())
类初始化参数检查
1:函数版
class Rag:
def __init__(self,name:str,age:int):
if not self.checkparameters(((name,str),(age,int))):
raise TypeError('Type Error!')
self._name=name
self._age=age
def checkparameters(self,params):
for data,type in params:
if not isinstance(data,type):
return False
return True
b=Rag('uiop',44)
2:类装饰器V1
class CheckParams:
def __init__(self,attr,annotation):
self.attr=attr
self.annotation=annotation
def __get__(self,instance,owner):
if instance is not None: #非类访问
return instance.__dict__[self.attr]
return self
def __set__(self,instance,value):
if not isinstance(value,self.annotation):
raise TypeError(r'{} should be type {}'.format(value,self.annotation))
instance.__dict__[self.attr]=value
class Rag:
name=CheckParams('name',str) # 硬编码
age=CheckParams('age',int)
def __init__(self,name:str,age:int):
self.name=name
self.age=age
p=Rag(22,22)
class CheckParams:
def __init__(self,attr,type):
self.attr=attr
self.type=type
pass
def __get__(self,instance,owner):
pass
def __set__(self,instance,value):
if not isinstance(value,self.type):
raise ValueError(r'{}'.format(value))
else:
instance.__dict__[self.attr]=value
pass
class Ore:
name=CheckParams('name',str)
age=CheckParams('age',int)
def __init__(self,name:str,age:any):
self.name=name
self.age=age
o=Ore('uiop',88)
print(o.__dict__)
import inspect
b=inspect.signature(Ore)
print(type(b),b)
print(b.parameters)
print(type(b.parameters['age']))
for k,v in b.parameters.items():
print(k,v.annotation)
3:类装饰器V2
class CheckParams:
def __init__(self,attr,annotation):
self.attr=attr
self.annotation=annotation
def __get__(self,instance,owner):
return instance.__dict__[self.attr]
def __set__(self,instance,value):
if not isinstance(value,self.annotation):
raise TypeError(r'{} should be type {}!'.format(value,self.annotation))
else:
instance.__dict__[self.attr]=value
import inspect
class TypeAssert:
def __init__(self,cls):
self.cls=cls
# setattr in self.cls
# OrderedDict([('name', <Parameter "name: str">), ('age', <Parameter "age">)])
params=inspect.signature(self.cls).parameters
for attr,param in params.items():
if param.annotation != param.empty: # annotation is not empty
setattr(self.cls,attr,CheckParams(attr,param.annotation))
def __call__(self,*args,**kwargs):
return self.cls(*args,**kwargs)
@TypeAssert
class Person:
def __init__(self,name:str,age:int):
self.name=name
self.age=age
p1=Person('uiop','77')
print(Person)
print(Person.__dict__['cls'].__dict__)
print(p1.__dict__)
print(p1.name)
4:函数装饰器
class CheckParams:
def __init__(self,attr,annotation):
self.attr=attr
self.annotation=annotation
def __get__(self,instance,owner):
if instance is not None:
return instance.__dict__[self.attr]
return self
def __set__(self,instance,value):
if not isinstance(value,self.annotation):
raise TypeError(r'{} should be type {}'.format(value,self.annotation))
instance.__dict__[self.attr]=value
import inspect
def typeassert(cls):
params=inspect.signature(cls).parameters
for attr,param in params.items():
if param.annotation != param.empty:
setattr(cls,attr,CheckParams(attr,param.annotation))
return cls
@typeassert # 添加描述器
class Ore:
def __init__(self,name:str,age:int):
self.name=name
self.age=age
def __repr__(self):
return 'name:{} age:{}'.format(self.name,self.age)
p=Ore('22',33)
print(Ore.__dict__) # 观察Ore属性的变化
print(p)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律