Stałe klasowe w Pythonie


128

W Pythonie chcę, aby klasa miała pewne „stałe” (praktycznie zmienne), które będą wspólne dla wszystkich podklas. Czy można to zrobić za pomocą przyjaznej składni? Obecnie używam:

class Animal:
    SIZES=["Huge","Big","Medium","Small"]

class Horse(Animal):
    def printSize(self):
        print(Animal.SIZES[1])

i zastanawiam się, czy istnieje lepszy sposób na zrobienie tego lub sposób na zrobienie tego bez konieczności pisania „Animal”. przed rozmiarami. Dzięki! edycja: zapomniałem wspomnieć, że koń dziedziczy po zwierzęciu.


16
Nie jest to pełna odpowiedź, ale jeśli SIZESnigdy się nie zmieni, zdecydowanie użyj krotki zamiast listy. Tak("Huge","Big","Medium","Small")
jamylak

Wygląda na to, że naprawdę szukasz tutaj wyliczenia
Eric

Odpowiedzi:


141

Ponieważ Horsejest to podklasa Animal, możesz po prostu zmienić

print(Animal.SIZES[1])

z

print(self.SIZES[1])

Mimo to musisz pamiętać, że SIZES[1]oznacza to „duży”, więc prawdopodobnie mógłbyś ulepszyć swój kod, wykonując coś takiego:

class Animal:
    SIZE_HUGE="Huge"
    SIZE_BIG="Big"
    SIZE_MEDIUM="Medium"
    SIZE_SMALL="Small"

class Horse(Animal):
    def printSize(self):
        print(self.SIZE_BIG)

Alternatywnie, można utworzyć klasy pośrednich: HugeAnimal, BigAnimal, i tak dalej. Byłoby to szczególnie pomocne, gdyby każda klasa zwierząt miała inną logikę.


SIZE_BIG = ["BigOne", "BigTwo"] powinienem używać tego typu stałej.
Lova Chittumuri

17

Możesz dostać się SIZESza pomocą self.SIZES(w metodzie instancji) lub cls.SIZES(w metodzie klasowej).

W każdym razie musisz wyraźnie określić, gdzie znaleźć SIZES. Alternatywą jest umieszczenie SIZESmodułu zawierającego klasy, ale wtedy musisz zdefiniować wszystkie klasy w jednym module.


Koń jest rzeczywiście podklasą zwierzęcia. Właściwie jest całkowicie możliwe użycie self.SIZES [1] zamiast Animal.SIZES [1].
betabandido

@betabandido: OP poprawił pytanie. Odpowiednio zaktualizuje odpowiedź.
Fred Foo

12
class Animal:
    HUGE = "Huge"
    BIG = "Big"

class Horse:
    def printSize(self):
        print(Animal.HUGE)

Możesz również uzyskać dostęp przez siebie, np. „self.HUGE” lub „self.BIG”. To działałoby tylko wewnętrznie w klasie.
cevaris

4

Rozwijając odpowiedź betabandido, możesz napisać funkcję, która wstrzyknie atrybuty jako stałe do modułu:

def module_register_class_constants(klass, attr_prefix):
    globals().update(
        (name, getattr(klass, name)) for name in dir(klass) if name.startswith(attr_prefix)
    )

class Animal(object):
    SIZE_HUGE = "Huge"
    SIZE_BIG = "Big"

module_register_class_constants(Animal, "SIZE_")

class Horse(Animal):
    def printSize(self):
        print SIZE_BIG

print SIZE_BIGpoza klasą będzie to samo? Czy będzie można go edytować Animal.SIZE_HUGE = 'Small'?
Crusader
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.