【发布时间】:2019-01-26 11:15:33
【问题描述】:
下面是解构类装饰器的源代码,我对在类中使用staticmethod有点困惑,因为如果我将代码klass.__new__ = staticmethod(__new__)更改为klass.__new__ = __new__,它仍然可以按预期工作,任何人都可以解释一下为什么在这里使用静态方法?目的或用例是什么?
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}
【问题讨论】: