【问题标题】:django deconstructible decorator staticmethoddjango 可解构装饰器静态方法
【发布时间】: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}

【问题讨论】:

    标签: python django


    【解决方案1】:

    方法默认是静态的:

    __new__() 是一个静态方法(特殊情况,因此您不需要这样声明),它将请求实例的类作为其第一个参数。

    https://docs.python.org/3.4/reference/datamodel.html#object.__new__

    所以klass.__new__ = staticmethod(__new__) 中的staticmehthod 只是明确地说它是一个静态方法。

    【讨论】:

      猜你喜欢
      • 2011-09-18
      • 1970-01-01
      • 2018-05-07
      • 1970-01-01
      • 2015-02-21
      • 2020-06-03
      • 2016-05-19
      • 2017-06-19
      • 1970-01-01
      相关资源
      最近更新 更多