2016-09-14 4 views
4

Ist es möglich, eine statische Eigenschaft für eine Klasse zu haben, die als eine einzige berechnet wird? Die Idee wäre in der Lage sein, es zu tun, wie so:Berechnete statische Eigenschaft in Python

class Foo: 
    static_prop = Foo.one_off_static_method() 

    @staticmethod 
    def one_off_static_method(): 
     return 'bar' 

ich dachte __new__ auch verwenden.

Class Foo: 
    def __new__(cls): 
     cls.static_prop = ... do everything here 

Nicht sicher die Auswirkungen davon, obwohl.

+0

Wollen Sie dies faul ausgewertet (und ist es eigentlich etwas ausreichend teuer und ausreichend wahrscheinlich nie verwendet werden, dass faule Auswertung Sinn macht)? – user2357112

+0

Haben Sie versucht, eine statische Methode zu einer Eigenschaft zu machen? – TankorSmash

+1

Möchten Sie, dass es bei der ersten Verwendung oder bei der Definition der Klasse berechnet wird? – wim

Antwort

3

Wenn Sie es bei Klassendefinition Zeit berechnet mögen, finden chepner's answer - obwohl ich nur statt eine Modul-Level-Funktion empfehlen würde, zu verwenden.

Wenn Sie wollen, dass es faul bewertet, dann könnte Sie interessiert sein, eine cached_property.

>>> from random import random 
>>> from cached_property import cached_property 
>>> class Foo(object): 
...  @cached_property 
...  def one_off_thing(self): 
...   print('computing...') 
...   return random() 
...  
>>> foo = Foo() 
>>> foo.one_off_thing 
computing... 
0.5804382038855782 
>>> foo.one_off_thing 
0.5804382038855782 

Hinweis: es jeden Mann und sein Hund scheint eine Implementierung von memo Dekorateure in Python hat, ist dies eine von vielen. Wenn Sie Python 3 verwenden, sollten Sie functools.lru_cache in Erwägung ziehen, da es sich um die Kernbibliotheken handelt.

+0

Dies würde einmal pro Instanz berechnet werden, richtig? – mkohram

+0

Ja, einmal pro Instanz. – wim

+0

Schöner Fund mit 'functools.lru_cache'. – mkohram

1

Bis die Klasse tatsächlich erstellt wird, ist one_off_static_method nur eine normale Funktion. Es muss definiert werden, bevor Sie versuchen, es aufzurufen, da Sie es aufrufen möchten, während die Anweisung class ausgeführt wird. Sobald Sie damit fertig sind, können Sie es einfach löschen.

class Foo: 
    def _one_off_static_method(): 
     return 'bar' 

    static_prop = _one_off_static_method() 
    del _one_off_static_method 
1

Hier gehen Sie, ich machte einen kleinen Descriptor für Sie :-)

Nach dem Zugriff auf das Attribut, wird es berechnet und zwischengespeichert werden.

class CachedStaticProperty: 
    """Works like @property and @staticmethod combined""" 

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

    def __get__(self, inst, owner): 
     result = self.func() 
     setattr(owner, self.func.__name__, result) 
     return result 

Die Funktionsweise ist denkbar einfach:

  1. die Dekorateur Syntax Bei Verwendung ich die Funktion intern speichern.
  2. Nach dem Zugriff, rufe ich die Funktion und legen Sie den Wert als Klassenwert mit dem gleichen Namen wie die ursprüngliche Funktion.

Das ist alles, was es ist. Einfach und effizient.

+0

Das ist cool. Immer noch nicht statisch;) – mkohram

+0

@mkohram Whoops, hier gehts :-) Es ist noch kleiner: P – Bharel

+0

@mkohram Eine kleine Erklärung hinzugefügt. – Bharel

Verwandte Themen