Wie erstelle ich statische Klassenvariablen oder Methoden in Python?
Antworten
Zu viele Anzeigen?Sie können auch erzwingen, dass eine Klasse statisch ist, indem Sie eine Metaklasse verwenden.
class StaticClassError(Exception):
pass
class StaticClass:
__metaclass__ = abc.ABCMeta
def __new__(cls, *args, **kw):
raise StaticClassError("%s is a static class and cannot be initiated."
% cls)
class MyClass(StaticClass):
a = 1
b = 3
@staticmethod
def add(x, y):
return x+y
Wenn Sie dann aus Versehen versuchen, die MyClass erhalten Sie einen StaticClassError.
Mit Objekt-Datentypen ist dies möglich. Aber mit primitiven Typen wie bool
, int
, float
o str
bahaviour unterscheidet sich von anderen OOP-Sprachen. Denn in geerbten Klassen gibt es keine statischen Attribute. Wenn das Attribut in der geerbten Klasse nicht vorhanden ist, sucht Python in der übergeordneten Klasse danach. Wenn es in der übergeordneten Klasse gefunden wird, wird sein Wert zurückgegeben. Wenn Sie sich entscheiden, den Wert in der geerbten Klasse zu ändern, wird das statische Attribut zur Laufzeit erstellt. Beim nächsten Lesen des geerbten statischen Attributs wird dessen Wert zurückgegeben, da es bereits definiert ist. Objekte (Listen, Dicts) funktionieren als Referenzen, so dass es sicher ist, sie als statische Attribute zu verwenden und sie zu erben. Die Objektadresse wird nicht geändert, wenn Sie die Attributwerte ändern.
Beispiel mit ganzzahligem Datentyp:
class A:
static = 1
class B(A):
pass
print(f"int {A.static}") # get 1 correctly
print(f"int {B.static}") # get 1 correctly
A.static = 5
print(f"int {A.static}") # get 5 correctly
print(f"int {B.static}") # get 5 correctly
B.static = 6
print(f"int {A.static}") # expected 6, but get 5 incorrectly
print(f"int {B.static}") # get 6 correctly
A.static = 7
print(f"int {A.static}") # get 7 correctly
print(f"int {B.static}") # get unchanged 6
Lösung basierend auf refdatatypes Bibliothek:
from refdatatypes.refint import RefInt
class AAA:
static = RefInt(1)
class BBB(AAA):
pass
print(f"refint {AAA.static.value}") # get 1 correctly
print(f"refint {BBB.static.value}") # get 1 correctly
AAA.static.value = 5
print(f"refint {AAA.static.value}") # get 5 correctly
print(f"refint {BBB.static.value}") # get 5 correctly
BBB.static.value = 6
print(f"refint {AAA.static.value}") # get 6 correctly
print(f"refint {BBB.static.value}") # get 6 correctly
AAA.static.value = 7
print(f"refint {AAA.static.value}") # get 7 correctly
print(f"refint {BBB.static.value}") # get 7 correctly
Ein sehr interessanter Punkt über Pythons Attribut-Lookup ist, dass es verwendet werden kann, um " virtuell Variablen":
class A(object):
label="Amazing"
def __init__(self,d):
self.data=d
def say(self):
print("%s %s!"%(self.label,self.data))
class B(A):
label="Bold" # overrides A.label
A(5).say() # Amazing 5!
B(3).say() # Bold 3!
Normalerweise werden diese nach ihrer Erstellung nicht mehr zugewiesen. Beachten Sie, dass die Suche mit self
denn, obwohl label
ist statisch in dem Sinne, dass es nicht mit einem besondere Instanz, hängt der Wert immer noch von der (Klasse der) Instanz ab.
Ja, es ist definitiv möglich, statische Variablen und Methoden in Python zu schreiben.
Statische Variablen : Die auf Klassenebene deklarierten Variablen werden als statische Variablen bezeichnet, auf die direkt über den Klassennamen zugegriffen werden kann.
>>> class A:
...my_var = "shagun"
>>> print(A.my_var)
shagun
Instanzvariablen: Variablen, die sich auf eine Instanz einer Klasse beziehen und auf die diese zugreift, sind Instanzvariablen.
>>> a = A()
>>> a.my_var = "pruthi"
>>> print(A.my_var,a.my_var)
shagun pruthi
Statische Methoden: Ähnlich wie bei Variablen kann auf statische Methoden direkt über die Klasse Name zugegriffen werden. Es ist nicht notwendig, eine Instanz zu erstellen.
Aber bedenken Sie, dass eine statische Methode in Python keine nicht-statische Methode aufrufen kann.
>>> class A:
... @staticmethod
... def my_static_method():
... print("Yippey!!")
...
>>> A.my_static_method()
Yippey!!
Ja, absolut, Python selbst hat kein statisches Datenelement explizit, aber wir können es haben, indem wir dies tun
class A:
counter =0
def callme (self):
A.counter +=1
def getcount (self):
return self.counter
>>> x=A()
>>> y=A()
>>> print(x.getcount())
>>> print(y.getcount())
>>> x.callme()
>>> print(x.getcount())
>>> print(y.getcount())
Ausgabe
0
0
1
1
Erklärung
here object (x) alone increment the counter variable
from 0 to 1 by not object y. But result it as "static counter"