【问题标题】:Modify method call if chained链接时修改方法调用
【发布时间】:2023-01-25 23:00:31
【问题描述】:

最好提供一个我猜的例子(有点伪代码......)

from django.db import transaction
from somewhere import some_job
from functools import partial

class Foo:

  def do_something(self, key, value):
    return some_job(key, value)
  
  @property
  def modifier(self):
    pass

f = Foo()
f.do_something(key='a', value=1) -> result

f.modifier.do_something(key='a', value=1) -> transaction.on_commit(partial(do_something, key='a', value=1))

通常如果做点什么被称为它会做常规的事情并返回一些结果, 但是当它通过链接时修饰符它应该返回 transaction.on_commit(partial(do_something, key='a', value=1)) 而不是常规结果。修饰符可能是类中的属性或其他内容。问题是这个实例是单调的,不应该永久更改,因为它最近会被其他代码使用。

无法全神贯注于如何做到这一点。 有任何想法吗?

【问题讨论】:

  • modifier 应该返回包装self 并且其do_something 方法委托给Foo.do_something 的某个其他类的实例。
  • 好吧,现在它看起来像描述符。 do_something 也是一个示例方法。可能需要修改的方法很少。它们的名称未知,因为它们可能在子类中定义
  • 特性描述符。 f.modifier 只是调用Foo.__dict__['modifier'].__get__(f, Foo),它返回 modifier 对象的 fget 属性在应用于 f 时返回的任何内容。 (换句话说,f.modifier == Foo.modifier.fget(f)。)

标签: python


【解决方案1】:
class Modifier(Foo):
    def do_something(this, key, value):
        transaction.on_commit(partial(super().do_something, key='a', value=1))

【讨论】:

    【解决方案2】:

    这确实修改了 foo 对象,但如果您更改 _lock 的名称,它应该可以工作,这样它就不会与其他属性冲突。

    from functools import partial
    
    class Foo:
      _lock = False
    
      def do_something(self, key, value):
        if self._lock:
          transaction.on_commit(partial(some_job, key, value))
          self._lock = False
        else:
          return some_job(key, value)
    
      def lock(self):
        self._lock = True
        return self
    
    # some mocks
    class Transaction:
      @staticmethod
      def on_commit(func):
        print("Transaction commit success.")
        func()
    
    some_job = lambda x, y: print("Some job", x, y)
    transaction = Transaction()
    # end mocks
    
    foo = Foo()
    
    print(">>> foo.do_something(...)")
    foo.do_something('key1', 'value1')
    # Some job key1 value1
    
    print(">>> foo.lock().do_something(...)")
    foo.lock().do_something('key2', 'value2')
    # Transaction commit success.
    # Some job key2 value2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多