大家好,又见面了,我是你们的朋友全栈君。
【传送门】
from functools import wraps
class A:
#作为一个实例方法
def decorator1(self,func):
@wraps(func)
def wrapper(*args, **kwargs):
print("decorator 1")
return func(*args,**kwargs)
return wrapper
#作为一个类方法
@classmethod
def decorator2(cls, func):
@wraps(func)
def wrapper(*args, **kwargs):
print("decorator 2")
return func(*args,**kwargs)
return wrapper
#作为实列使用
a = A()
@a.decorator1
def spam():
print('spam')
#作为类方法使用
@A.decorator2
def grok():
print("grok")
class Person:
first_name = property()
@first_name.getter
def first_name(self):
return self._first_name
@first_name.setter
def first_name(self,value):
if not isinstance(value,str):
raise TypeError("Expected a string")
self._first_name = value
import types
from functools import wraps
class Profiled:
def __init__(self,func):
wraps(func)(self)
self.ncalls = 0
def __call__(self,*args, **kwargs):
self.ncalls += 1
return self.__wrapped__(*args, **kwargs)
def __get__(self, instance, cls):
if instance is None:
return self
else:
return types.MethodType(self,instance)
@Profiled
def add(x, y):
return x + y
class Spam:
@Profiled
def bar(self, x):
print(self, x)
add(2,3)
5
add(4,5)
9
add.ncalls
2
s = Spam()
s.bar(1)
<__main__.Spam object at 0x00B65350> 1
s.bar(2)
<__main__.Spam object at 0x00B65350> 2
s.bar(10)
<__main__.Spam object at 0x00B65350> 10
Spam.bar.ncalls
3
import types
from functools import wraps
def profiled(func):
ncalls = 0
@wraps(func)
def wrapper(*args,**kwargs):
nonlocal ncalls
ncalls += 1
return func(*args, **kwargs)
wrapper.ncalls = lambda: ncalls
return wrapper
@profiled
def add(x,y):
return x+y
add(2,3)
5
add(3,4)
7
add.ncalls()
2
import time
from functools import wraps
def timethis(func):
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
r = func(*args,**kwargs)
end = time.time()
print(end-start)
return r
return wrapper
class Spam:
@timethis
def instance_method(self, n ):
print(self, n)
while n > 0:
n -= 1
@classmethod
@timethis
def class_method(cls,n):
print(cls,n)
while n > 0:
n -= 1
@staticmethod
@timethis
def static_method(n):
print(n)
while n > 0:
n -= 1
s = Spam()
s.instance_method(10000000)
<__main__.Spam object at 0x00B79510> 10000000
0.7324073314666748
Spam.class_method(1000000)
<class '__main__.Spam'> 1000000
0.12408709526062012
Spam.static_method(10000000)
10000000
0.8057591915130615
from abc import ABCMeta, abstractmethod
class A(metaclass=ABCMeta):
@classmethod
@abstractmethod
def method(cls):
pass
from functools import wraps
def optional_debug(func):
@wraps(func)
def wrapper(*args, debug=False, **kwargs):
if debug:
print('Calling ', func.__name__)
return func(*args,**kwargs)
return wrapper
@optional_debug
def spam(a,b,c):
print(a,b,c)
spam(1,2,3)
1 2 3
spam(1,2,3,debug=True)
Calling spam
1 2 3
def a(x,debug=False):
if debug:
print("calling a")
def b(x,y,z,debug=False):
if debug:
print("calling b")
def c(x,y,debug=False):
print("calling c")
# 我们可以将上述代码重写为:
from functools import wraps
import inspect
def optional_debug(func):
if 'debug' in inspect.getfullargspec(func).args:
raise TypeError("debug argument already defined")
@wraps(func)
def wrapper(*args, debug=False, **kwargs):
if debug:
print("calling ",func.__name__)
return func(*args,**kwargs)
return wrapper
@optional_debug
def a(x):
pass
@optional_debug
def b(x,y,z):
pass
@optional_debug
def c(x,y):
pass
def log_getattribute(cls):
orig_getattribute = cls.__getattribute__
def new_getattribute(self, name):
print("getting : ",name)
return orig_getattribute(self, name)
cls.__getattribute__ = new_getattribute
return cls
@log_getattribute
class A:
def __init__(self, x):
self.x = x
def spam(self):
pass
a = A(22)
a.x
getting : x
22
a.spam()
getting : spam
# 我们知道python创建的类可以像函数一样调用它来创建实例
class Spam:
def __init__(self,name):
self.name = name
a = Spam("Guido")
b = Spam("Diana")
# 假设我们不想让任何人创建该类的实例
class NoInstance(type):
def __call__(self,*args,**kwargs):
raise TypeError("can't instance directly")
class Spam(metaclass=NoInstance):
@staticmethod
def grok(x):
print("Spam.grok")
#这样我们只能调用该类的静态方法,而不能进行实例化
Spam.grok(42)
Spam.grok
s = Spam()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-ee1b074714bf> in <module>()
----> 1 s = Spam()
<ipython-input-28-8781af2ac6ac> in __call__(self, *args, **kwargs)
2 class NoInstance(type):
3 def __call__(self,*args,**kwargs):
----> 4 raise TypeError("can't instance directly")
5 class Spam(metaclass=NoInstance):
6 @staticmethod
TypeError: can't instance directly
class Singleton(type):
def __init__(self, *args,**kwargs):
self.__instance = None
super().__init__(*args,**kwargs)
def __call__(self,*args, **kwargs):
if self.__instance is None:
self.__instance = super().__call__(*args, **kwargs)
return self.__instance
else:
return self.__instance
class Spam(metaclass = Singleton):
def __init__(self):
print("creating Spam")
a = Spam()
creating Spam
b = Spam()
a == b
True
a is b
True
import weakref
class Cached(type):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__cache = weakref.WeakValueDictionary()
def __call__(self, *args):
if args in self.__cache:
return self.__cache[args]
else:
obj = super().__call__(*args)
self.__cache[args] = obj
return obj
class Spam(metaclass=Cached):
def __init__(self,name):
print("creating Spam({!r})".format(name))
self.name = name
a = Spam('Guodo')
creating Spam('Guodo')
b = Spam("Diana")
creating Spam('Diana')
c = Spam("Guodo")
#注意上面并没有重新创建
a is c
True
a is b
False
from collections import OrderedDict
class Typed:
_expected_type = type(None)
def __init__(self,name=None):
self._name = name
def __set__(self, instance, value):
if not isinstance(value, self._expected_type):
raise TypeError('type Error')
instance.__dict__[self._name] = value
class Integer(Typed):
_expected_type = int
class Float(Typed):
_expected_type = float
class String(Typed):
_expected_type = str
class OrderMeta(type):
def __new__(cls, clsname, bases, clsdict):
d = dict(clsdict)
order = []
for name, value in clsdict.items():
if isinstance(value, Typed):
value._name = name
order.append(name)
d['_order'] = order
return type.__new__(cls, clsname, bases, d)
@classmethod
def __prepare__(cls, clsname, bases):
return OrderedDict()
class Structure(metaclass=OrderMeta):
def as_csv(self):
return ','.join(str(getattr(self,name)) for name in self._order)
class Stock(Structure):
name = String()
shares = Integer()
price = Float()
def __init__(self, name, shares, price):
self.name = name
self.shares = shares
self.price = price
s = Stock("google",100, 234.19)
s.name
'google'
s.as_csv()
'google,100,234.19'
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/136690.html原文链接:https://javaforall.cn