2 Stimmen

Ersetzen einer Instanzmethode

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'

Ist mein Verständnis richtig?

Ich versuche, dies auf folgende Weise zu nutzen:

  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
        # ...

Würde dies korrekt funktionieren? Ist es in Ordnung, dies zu tun? Ursprünglich hatte ich gehofft, Zeit zu sparen im Vergleich zur Überprüfung self.cache_field bei jedem Aufruf von calculate_attributes aber ich bin mir nicht mehr sicher, ob das Zeit sparen würde.

3voto

senderle Punkte 135243

Ich denke, der Grundgedanke ist richtig, mit ein paar kleinen Korrekturen. Erstens,

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

Das sollte lauten Klasse Methode, nicht Instanzmethode. Du änderst hier die Klasse. Und zweitens entspricht das hier keiner definierten Variable:

    if cache is None:

Vielleicht meinen Sie ja cache_field ?

Im Allgemeinen ist das Setzen von Instanzattributen in __init__ ist völlig normal und akzeptabel. Es spielt keine Rolle, dass es sich um eine Methode handelt und nicht um eine andere Art von Objekt - es ist nicht anders, als wenn man sagt self.foo = 'bar' .

Manchmal hängt dies auch davon ab, aber im Allgemeinen ist es tatsächlich schneller, die Methode in init als zu testen cache_field jedes Mal check_cache genannt wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X