Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将默认修饰符应用于类上的所有方法,并有选择地排除它们_Python_Python 2.7_Python Decorators - Fatal编程技术网

Python 将默认修饰符应用于类上的所有方法,并有选择地排除它们

Python 将默认修饰符应用于类上的所有方法,并有选择地排除它们,python,python-2.7,python-decorators,Python,Python 2.7,Python Decorators,我有一个包含大量方法的类,其中大多数方法要求首先运行一个方法来填充类中的列表。但是,我也希望使用延迟加载,这样我就可以在不使用初始加载的情况下创建实例,直到调用需要重载的方法为止。因此,我想创建一个类,其中假设所有方法都需要运行给定的方法,除非有选择地排除该方法。以下是我的伪代码: @all_methods_run_load class myClass things = [] params = [] @dont_run_load def __init__(sel

我有一个包含大量方法的类,其中大多数方法要求首先运行一个方法来填充类中的列表。但是,我也希望使用延迟加载,这样我就可以在不使用初始加载的情况下创建实例,直到调用需要重载的方法为止。因此,我想创建一个类,其中假设所有方法都需要运行给定的方法,除非有选择地排除该方法。以下是我的伪代码:

@all_methods_run_load
class myClass
    things = []
    params = []

    @dont_run_load
    def __init__(self, params):
      self.params = params

    @dont_run_load
    def load(self):
      self.things = do_a_ton_stuff()

    def get_things():
      return self.things

    def get_some_things():
      return apply_a_filter(self.things)

    def get_first_thing():
      return self.things[0]

    def get_last_thing():
      return self.things[-1]

希望这是有道理的。我对装潢师自己还很陌生,还记得他们,所以我担心答案可能会让我大吃一惊,然而我突然想到了这个问题,我忍不住进一步调查:)

我对你想要实现的目标有点困惑。如果您想进行延迟加载,为什么不使用需要对仅第一次计算的属性进行数据调用的函数呢

class myClass
    _things = []
    params = []

    def __init__(self, params):
      self.params = params

    @property
    def things(self):
      if not self._things:
          self._things = do_a_ton_stuff()
      return self._things

    def get_things():
      return self.things

    def get_some_things():
      return apply_a_filter(self.things)

    def get_first_thing():
      return self.things[0]

    def get_last_thing():
      return self.things[-1]

有些人会为这种图案制作一个@cachedproperty装饰器,这样他们就不必自己动手了

虽然艾丹·凯恩(Aidan Kane)认为你不应该这样做可能是正确的,但你所陈述的问题的解决方案可以这样表述:

下面是可以修饰这些方法的函数

import functools

def run_load(function):
    """Make a function run the class' load method before running."""
    @functools.wraps(function)
    def inner(self, *args, **kwargs):
        self.load()
        return function(self, *args, **kwargs)
    return inner
函数是可变的,所以您可以只标记它们

def without_load(function):
    """Tag a method so that it shouldn't be decorated to call self.load."""
    function.without_load = True
    return function
只需遍历类的成员并
setattr
-ing它们(),就可以装饰类

就这样

def should_be_loaded(function):
    try:
        return not bool(function.without_load)
    except AttributeError:
        return True

@decorate_all_with(run_load, should_be_loaded)
class MyClass:
        things = []
        params = []

        @without_load
        def __init__(self, params):
            self.params = params

        @without_load
        def load(self):
            self.things = do_a_ton_stuff()

        def get_things(self):
            return self.things

        def get_some_things(self):
            return apply_a_filter(self.things)

        def get_first_thing(self):
            return self.things[0]

        def get_last_thing(self):
            return self.things[-1]

还可以将所有其他getter转换为属性。哦,是的,为什么我没有想到这一点@邓肯:这种转换会带来什么好处?@DanH,在这种情况下,它只会让使用它的代码更干净一些;您可以使用
instance.things
instance.last\u thing
而不是
instance.get\u things()
instance.get\u last\u thing()
这样每次访问属性时就少了6个字符。一般来说,如果你直接访问属性,那么代码会更快,也会更短,然后你就可以在这种情况下使用属性,在这种情况下,你不需要重写使用属性的代码。我同意邓肯的建议。实际上,您不需要在其中使用其他方法。人们可以像阅读和理解obj.things[-1]一样快速地阅读和理解obj.last_things——然而,有些东西可能是一种财产。非常酷,谢谢,但我同意你的观点,艾丹·凯恩的观点可能是最好的途径。很高兴阅读您的解决方案:)
def should_be_loaded(function):
    try:
        return not bool(function.without_load)
    except AttributeError:
        return True

@decorate_all_with(run_load, should_be_loaded)
class MyClass:
        things = []
        params = []

        @without_load
        def __init__(self, params):
            self.params = params

        @without_load
        def load(self):
            self.things = do_a_ton_stuff()

        def get_things(self):
            return self.things

        def get_some_things(self):
            return apply_a_filter(self.things)

        def get_first_thing(self):
            return self.things[0]

        def get_last_thing(self):
            return self.things[-1]