Method delegation in python

后端 未结 2 1585
无人及你
无人及你 2021-02-14 03:00

I\'m writing a small framework for orchestrating AWS clusters and there are some common hierarchical patterns that appear over and over again. One such pattern is gathering a co

2条回答
  •  梦如初夏
    2021-02-14 03:15

    __getattr__ is called when the whole class hirarchy is traversed and the attribute is not found. So it is better to generate the method once and store it in the class. Then finding the method takes less time next time.

    >>> X.a
    
    Traceback (most recent call last):
      File "", line 1, in 
        X.a
    AttributeError: class X has no attribute 'a'
    >>> x.a
    new delegator
    
    >>> x.a
    >
    >>> X.a
    
    

    Here you can see the adaption of your code to do that:

    class NonDelegatableItem(AttributeError):
        pass
    
    class X:
        def __getattr__(self, method_name):
            self.check_method_name_is_delegator(method_name)
            return self.create_delegator(method_name)
    
        def check_method_name_is_delegator(self, method_name):
            if method_name not in self._allowed_items:
                raise NonDelegatableItem('{} can not be delegated'.format(method_name))
    
        @classmethod
        def create_delegator(cls, method_name):
            print 'new delegator'
            def delegator(self, *args, **kw):
                self.check_method_name_is_delegator(method_name)
                for instance in self.all_instances:
                    getattr(instance, method_name)(*args, **kw)
            setattr(cls, method_name, delegator)
            return delegator
    
    
    x = X()
    
    x._allowed_items = ['a', 'b']
    

提交回复
热议问题