以下是deconstruct类装饰器的源代码,我对类中使用staticmethod感到有些困惑,因为如果将代码klass.__new__ = staticmethod(__new__)
更改为klass.__new__ = __new__
,它仍然可以正常工作意料之中,谁能解释我为什么在这里使用staticmethod?目的或用例是什么?
from importlib import import_module
def deconstructible(*args, path=None):
"""
Class decorator that allows the decorated class to be serialized
by the migrations subsystem.
The `path` kwarg specifies the import path.
"""
def decorator(klass):
def __new__(cls, *args, **kwargs):
# We capture the arguments to make returning them trivial
obj = super(klass, cls).__new__(cls)
obj._constructor_args = (args, kwargs)
return obj
def deconstruct(obj):
"""
Return a 3-tuple of class import path, positional arguments,
and keyword arguments.
"""
# Fallback version
if path:
module_name, _, name = path.rpartition('.')
else:
module_name = obj.__module__
name = obj.__class__.__name__
# Make sure it's actually there and not an inner class
module = import_module(module_name)
if not hasattr(module, name):
raise ValueError(
"Could not find object %s in %s.\n"
"Please note that you cannot serialize things like inner "
"classes. Please move the object into the main module "
"body to use migrations.\n"
"For more information, see "
"https://docs.djangoproject.com/en/%s/topics/migrations/#serializing-values"
% (name, module_name, get_docs_version()))
return (
path or '%s.%s' % (obj.__class__.__module__, name),
obj._constructor_args[0],
obj._constructor_args[1],
)
klass.__new__ = staticmethod(__new__)
# klass.__new__ = __new__
# add deconstruct method to the new class
klass.deconstruct = deconstruct
return klass
if not args:
return decorator
return decorator(*args)
# test class
@deconstructible
class A:
def __init__(self, a, *args, c= None, **kwargs):
self.a = a
self.c = c
if __name__ =='__main__':
a = A(10, c=100, f=10)
p,args,kwargs = a.deconstruct() # __main__.A (10,) {'c': 100, 'f': 10}
print(p, args, kwargs)
b = A(5,c=10, f=200)
pb, args_b, kwargs_b = A.deconstruct(b)
print(pb, args_b, kwargs_b) # __main__.A (5,) {'c': 10, 'f': 200}
答案 0 :(得分:1)
默认情况下该方法是静态的:
__new__()
是一个静态方法(特殊情况,因此您无需这样声明),它将请求实例的类作为其第一个参数。
https://docs.python.org/3.4/reference/datamodel.html#object.new
因此staticmehthod
中的klass.__new__ = staticmethod(__new__)
只是要明确地说这是一个静态方法。