替换实例方法

发布于 2025-01-02 17:59:26 字数 1591 浏览 1 评论 0原文

class A:
  def f(self):
    print('f')
  def g(self):
    print('g')
  def h(self):
    print('h')

x = A()
y = A()
x.f = x.g # creates a new attribute 'f' for x
x.f() # 'g'; resolves at the instance attribute level to call instance method 'g'
y.f() # 'f'; instance methods are unaffected
A.f = A.h # redefines instance method 'f' to print 'h'
x.f() # 'g'; still resolves at the attribute level to call instance method 'g'
y.f() # 'h'; instance method 'f' now prints 'h'
A.g = A.h # redefines instance method 'g' to print 'h'
x.f() # 'g'; still calls the old instance method 'g' because it kept the link to it
y.f() # 'h'

我的理解正确吗?

我尝试按以下方式使用它:

  class Attributes:
    def __init__(self, params, cache_field = None):
      # ...
      self.cache_field = cache_field
      if cache_field is None:
        # I hope I'm setting instance attribute only
        self.check_cache = self.check_external_cache
      else:
        self.check_cache = self.check_internal_cache
        self.internal_cache = {}

    def check_internal_cache(self, record):
      return self.internal_cache[record.id]

    def check_external_cache(self, record):
      return record[self.cache_field]

    def calculate_attributes(self, record):
      try:
        return self.check_cache(record) # I hope it will resolve to instance attribute
      except KeyError:
        # calculate and cache the value here
        # ...

这可以正常工作吗?这样做可以吗?最初,我希望与每次调用 calculate_attributes 时检查 self.cache_field 相比能够节省时间;但我不再确定它会节省任何时间。

class A:
  def f(self):
    print('f')
  def g(self):
    print('g')
  def h(self):
    print('h')

x = A()
y = A()
x.f = x.g # creates a new attribute 'f' for x
x.f() # 'g'; resolves at the instance attribute level to call instance method 'g'
y.f() # 'f'; instance methods are unaffected
A.f = A.h # redefines instance method 'f' to print 'h'
x.f() # 'g'; still resolves at the attribute level to call instance method 'g'
y.f() # 'h'; instance method 'f' now prints 'h'
A.g = A.h # redefines instance method 'g' to print 'h'
x.f() # 'g'; still calls the old instance method 'g' because it kept the link to it
y.f() # 'h'

Is my understanding correct?

I'm trying to use this in the following way:

  class Attributes:
    def __init__(self, params, cache_field = None):
      # ...
      self.cache_field = cache_field
      if cache_field is None:
        # I hope I'm setting instance attribute only
        self.check_cache = self.check_external_cache
      else:
        self.check_cache = self.check_internal_cache
        self.internal_cache = {}

    def check_internal_cache(self, record):
      return self.internal_cache[record.id]

    def check_external_cache(self, record):
      return record[self.cache_field]

    def calculate_attributes(self, record):
      try:
        return self.check_cache(record) # I hope it will resolve to instance attribute
      except KeyError:
        # calculate and cache the value here
        # ...

Would this work correctly? Is it ok to do this? Originally I was hoping to save time compared to checking self.cache_field in every call to calculate_attributes; but I'm no longer sure it would save any time.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

鹤仙姿 2025-01-09 17:59:26

我认为这里的基本想法是正确的,但有一些小的修正。首先,

A.f = A.h # redefines instance method 'f' to print 'h'

应该读取方法,而不是实例方法。你要在这里改变班级。其次,这与这里定义的任何变量都不对应:

    if cache is None:

我想您的意思可能是 cache_field

一般来说,在 __init__ 中设置实例属性是完全正常且可以接受的。这是一个方法而不是其他类型的对象并不重要——这与 self.foo = 'bar' 没有任何不同。

另外,有时这取决于情况,但总的来说,在 init 中设置方法确实比每次调用 check_cache 时测试 cache_field 更快。

I think the basic idea here is correct, with a couple of minor corrections. First,

A.f = A.h # redefines instance method 'f' to print 'h'

That should read class method, not instance method. You're changing the class here. And second, this doesn't correspond to any defined variable here:

    if cache is None:

I guess maybe you mean cache_field?

In general, setting instance attributes in __init__ is perfectly normal and acceptable. It doesn't matter that this is a method rather than some other kind of object -- it's not any different from saying self.foo = 'bar'.

Also, sometimes this depends, but in general, it is indeed faster to set the method in init than to test cache_field every time check_cache is called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文