2015-04-22 11 views
6

Dies ist hauptsächlich eine Frage des "guten Python-Stils".Gruppenkonstanten in Python

Ich habe ein Modul, das eine Anzahl von Konstanten verwendet, die sich gruppiert fühlen soll.

Lets sagen, wir haben Hunde und Katzen und jeder von ihnen haben die Anzahl der Beine und Lieblingsessen.

Beachten Sie, dass

  1. wir nichts anderes als diese Konstanten über Hunde modellieren und Katzen
  2. sehr wahrscheinlich werden wir mehr Tiere in der Zukunft haben.
  3. Diese Konstanten werden nicht außerhalb des aktuellen Moduls verwendet.

Ich dachte an den folgenden Lösungen:


Konstanten auf Modulebene

DOG_NUMBER_OF_LEGS = 4 
DOG_FAVOURITE_FOOD = ["Socks", "Meat"] 
CAT_NUMBER_OF_LEGS = 4 
CAT_FAVOURITE_FOOD = ["Lasagna", "Fish"] 

Sie scheinen nicht wirklich gruppierten, aber ich denke, es ist die Lösung, die ich bevorzuge.


Klassen als Namespaces

class Dog(object): 
    NUMBER_OF_LEGS = 4 
    DOG_FAVOURITE_FOOD = ["Socks", "Meat"] 
class Cat(object): 
    NUMBER_OF_LEGS = 4 
    FAVOURITE_FOOD = ["Lasagna", "Fish"] 

ich diese Lösung nicht wie wir Klasse haben werden, die wir verwenden gewohnt und sie können tatsächlich instanziiert werden.


Wörterbuch der Konstanten

ANIMALS_CONFIG = { 
    "DOG" : { 
    "NUMBER_OF_LEGS" : 4, 
    "FAVOURITE_FOOD" : ["Socks", "Meat"] 
    }, 
    "CAT" : { 
    "NUMBER_OF_LEGS" : 4, 
    "FAVOURITE_FOOD" : ["Lasagna", "Fish"] 
    } 
} 

Ich dachte auch über Submodule Zugabe, aber ich möchte nicht wirklich diese internen Konstanten belichten


was ist die pythonic Weg mach es/wie würdest du es machen?

+2

Sie auch eine Klasse '' mit Tier: ein Tier dog' haben könnte und 'cat' Instanzen dieser Klasse. – syntonym

+4

Oder Sie könnten auch [named tuples] (https://docs.python.org/2.7/library/collections.html#collections.namedtuple) verwenden. – syntonym

+0

Wie werden Sie sie in Ihrem Code verwenden? Wird iteriert oder ausgewählt? Woher käme der Auswahlparameter? –

Antwort

6

Ich würde für eine vierte Option gehen, ein lieber collections.namedtuple:

Animal = namedtuple('Animal', 'number_of_legs favourite_food') 

Sie dann Instanzen wie erstellen:

DOG = Animal(4, ['Socks', 'Meat']) 
CAT = Animal(4, ['Lasagna', 'Fish']) 

und die Werte zugreifen extern:

from animals import CAT 

print CAT.number_of_legs 

Es hat wirklich keinen Sinn, Klassen zu haben, wenn Sie keine Methoden erstellen müssen, und ich denke, die für m Zugang oben ist ordentlicher als z.B .:

from animals import animals 

print animals['CAT']['number_of_legs'] 

namedtuple s, wie Vanille tuple s, sind unveränderlich auch, so dass Sie nicht versehentlich zum Beispiel neu zuweisen können CAT.number_of_legs = 2 irgendwo.

Schließlich ist die namedtuple eine leichte Datenstruktur, die wichtig sein kann, wenn Sie viele Tiere zu schaffen:

>>> import sys 
>>> sys.getsizeof({'number_of_legs': 4, 'favourite_food': ['Lasagna', 'Fish']}) 
140 
>>> from collections import namedtuple 
>>> Animal = namedtuple('Animal', 'number_of_legs favourite_food') 
>>> sys.getsizeof(Animal(4, ['Lasagna', 'Fish'])) 
36 
1

Ich würde für das Wörterbuch Ansatz gehen, wie es lesbarer und besser organisiert fühlt, aber ich glaube, es ist eine Frage der persönlichen Vorliebe.

Das Verwenden von Klassen scheint auch keine schlechte Idee zu sein, wenn Sie eine Klasse mit nur statischen Variablen und Methoden wie this verwenden und diese niemals instanziieren.

4

Es gibt keine allgemeingültige Antwort, es hängt wirklich davon ab, wie viele Konstanten Sie handhaben müssen, wie Sie sie verwenden, ob Polymorphismus sinnvoll ist oder nicht und die Phase des Mondes.

Jetzt in Ihrem Beispiel, da Sie zwei oder mehr Sätze von Konstanten mit einer ähnlichen Struktur und Bedeutung haben, würde ich für die Lösung "Klassen als Namespaces" gehen.

FWIW eine Klasse verhindert instanziiert wird, ist nicht so schwierig:

>>> class Foo(object): 
... def __new__(cls): 
...  return cls 
... 
>>> Foo() 
<class '__main__.Foo'> 

Aber Dokumentation sollte genug sein - denken Sie daran, dass Ihre „Konstanten“ sind nur Konstanten, die durch Konvention ohnehin.