2569 Stimmen

Statische Klassenvariablen und Methoden in Python

Wie erstelle ich statische Klassenvariablen oder Methoden in Python?

10voto

Yann Punkte 30643

Diesbezüglich Antwort für eine Konstante statischen Variablen können Sie einen Deskriptor verwenden. Hier ist ein Beispiel:

class ConstantAttribute(object):
    '''You can initialize my value but not change it.'''
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, type=None):
        return self.value

    def __set__(self, obj, val):
        pass

class Demo(object):
    x = ConstantAttribute(10)

class SubDemo(Demo):
    x = 10

demo = Demo()
subdemo = SubDemo()
# should not change
demo.x = 100
# should change
subdemo.x = 100
print "small demo", demo.x
print "small subdemo", subdemo.x
print "big demo", Demo.x
print "big subdemo", SubDemo.x

was zu ...

small demo 10
small subdemo 100
big demo 10
big subdemo 10

Sie können immer eine Ausnahme auslösen, wenn Sie den Einstellwert ignorieren ( pass oben) ist nicht Ihr Ding. Wenn Sie nach einer statischen Klassenvariable im Stil von C++ oder Java suchen:

class StaticAttribute(object):
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, type=None):
        return self.value

    def __set__(self, obj, val):
        self.value = val

Werfen Sie einen Blick auf diese Antwort und die offiziellen Dokumente HOWTO für weitere Informationen über Deskriptoren.

7voto

Tomer Zait Punkte 1547

Der beste Weg, den ich gefunden habe, ist, eine andere Klasse zu verwenden. Sie können ein Objekt erstellen und es dann auf andere Objekte anwenden.

class staticFlag:
    def __init__(self):
        self.__success = False
    def isSuccess(self):
        return self.__success
    def succeed(self):
        self.__success = True

class tryIt:
    def __init__(self, staticFlag):
        self.isSuccess = staticFlag.isSuccess
        self.succeed = staticFlag.succeed

tryArr = []
flag = staticFlag()
for i in range(10):
    tryArr.append(tryIt(flag))
    if i == 5:
        tryArr[i].succeed()
    print tryArr[i].isSuccess()

Für das obige Beispiel habe ich eine Klasse namens staticFlag .

Diese Klasse sollte die statische var __success (Private statische Var).

tryIt Klasse repräsentiert die reguläre Klasse, die wir verwenden müssen.

Jetzt habe ich ein Objekt für eine Flagge ( staticFlag ). Dieses Kennzeichen wird als Referenz an alle regulären Objekte gesendet.

Alle diese Objekte werden in die Liste aufgenommen tryArr .


Dieses Skript ergibt:

False
False
False
False
False
True
True
True
True
True

7voto

HIMANSHU PANDEY Punkte 799

Wenn man die Antworten der anderen zusammenfasst und hinzufügt, gibt es viele Möglichkeiten, statische Methoden oder Variablen in python .

1. Verwendung von staticmethod() als Dekorateur:

Man kann einfach einen Dekorator über eine deklarierte Methode (Funktion) setzen, um sie zu einer statischen Methode zu machen. Zum Beispiel.

class Calculator:
    @staticmethod
    def multiply(n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 * n2 * Res

print(Calculator.multiply(1, 2, 3, 4))              # 24

2. Verwendung von staticmethod() als eine Parameterfunktion:

Diese Methode kann ein Argument vom Typ Funktion erhalten und gibt eine statische Version der übergebenen Funktion zurück. Zum Beispiel.

class Calculator:
    def add(n1, n2, *args):
        return n1 + n2 + sum(args)

Calculator.add = staticmethod(Calculator.add)
print(Calculator.add(1, 2, 3, 4))                   # 10

3. Verwendung von classmethod() als Dekorateur:

@classmethod hat ähnliche Auswirkungen auf eine Funktion wie @staticmethod, aber dieses Mal wird ein zusätzliches Argument benötigt, um in der Funktion akzeptiert zu werden (ähnlich dem self-Parameter für Instanzvariablen). Zum Beispiel.

class Calculator:
    num = 0
    def __init__(self, digits) -> None:
        Calculator.num = int(''.join(digits))

    @classmethod
    def get_digits(cls, num):
        digits = list(str(num))
        calc = cls(digits)
        return calc.num

print(Calculator.get_digits(314159))                # 314159

4. Verwendung von classmethod() als eine Parameterfunktion:

@classmethod kann auch als Parameterfunktion verwendet werden, wenn man die Klassendefinition nicht ändern möchte. Zum Beispiel.

class Calculator:
    def divide(cls, n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 / n2 / Res

Calculator.divide = classmethod(Calculator.divide)

print(Calculator.divide(15, 3, 5))                  # 1.0

5. Direkte Erklärung

Eine Methode/Variable, die außerhalb aller anderen Methoden, aber innerhalb einer Klasse deklariert wird, ist automatisch statisch.

class Calculator:   
    def subtract(n1, n2, *args):
        return n1 - n2 - sum(args)

print(Calculator.subtract(10, 2, 3, 4))             # 1

Das gesamte Programm

=======================

class Calculator:
    num = 0
    def __init__(self, digits) -> None:
        Calculator.num = int(''.join(digits))

    @staticmethod
    def multiply(n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 * n2 * Res

    def add(n1, n2, *args):
        return n1 + n2 + sum(args)

    @classmethod
    def get_digits(cls, num):
        digits = list(str(num))
        calc = cls(digits)
        return calc.num

    def divide(cls, n1, n2, *args):
        Res = 1
        for num in args: Res *= num
        return n1 / n2 / Res

    def subtract(n1, n2, *args):
        return n1 - n2 - sum(args)

Calculator.add = staticmethod(Calculator.add)
Calculator.divide = classmethod(Calculator.divide)

print(Calculator.multiply(1, 2, 3, 4))              # 24
print(Calculator.add(1, 2, 3, 4))                   # 10
print(Calculator.get_digits(314159))                # 314159
print(Calculator.divide(15, 3, 5))                  # 1.0
print(Calculator.subtract(10, 2, 3, 4))             # 1

Siehe Python-Dokumentation für die Beherrschung von OOP in Python.

6voto

Ross Punkte 1395

Um jede mögliche Verwirrung zu vermeiden, möchte ich statische Variablen und unveränderliche Objekte gegenüberstellen.

Einige primitive Objekttypen wie Integers, Floats, Strings und Tuples sind in Python unveränderlich. Das bedeutet, dass sich das Objekt, auf das ein bestimmter Name verweist, nicht ändern kann, wenn es zu einem der oben genannten Objekttypen gehört. Der Name kann einem anderen Objekt zugewiesen werden, aber das Objekt selbst kann nicht geändert werden.

Eine Variable statisch zu machen, geht noch einen Schritt weiter, indem es dem Variablennamen untersagt, auf ein anderes Objekt zu zeigen als das, auf das er gerade zeigt. (Hinweis: Dies ist ein allgemeines Software-Konzept und nicht spezifisch für Python; Informationen zur Implementierung von Statik in Python finden Sie in anderen Beiträgen).

5voto

jmunsch Punkte 19387

Statische Variablen in der Klassenfabrik python3.6

Für alle, die eine Klassenfabrik mit python3.6 und aufwärts verwenden die nonlocal Schlüsselwort, um es dem Bereich/Kontext der zu erstellenden Klasse hinzuzufügen, wie folgt:

>>> def SomeFactory(some_var=None):
...     class SomeClass(object):
...         nonlocal some_var
...         def print():
...             print(some_var)
...     return SomeClass
... 
>>> SomeFactory(some_var="hello world").print()
hello world

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