So verweisen Sie explizit auf eine Funktion/Klasse in einem Python-Modul, um Namenskollisionen zu vermeidenPython

Python-Programme
Anonymous
 So verweisen Sie explizit auf eine Funktion/Klasse in einem Python-Modul, um Namenskollisionen zu vermeiden

Post by Anonymous »

Ich versuche, ein kleines Python-Modul zu erstellen, um von einer Einheit in eine andere zu konvertieren (aus ähnlichem Code, den ich schon seit Ewigkeiten in Matlab habe und der meinen Anforderungen entspricht).
Ich habe daher eine erste Aufzählungsklasse erstellt, die für verfügbare Metriken definiert werden soll:

Code: Select all

## --- Imports
from enum import auto, Enum

## --- Metrics
class Metric(Enum):
#[
DimensionLess = auto()
Mass = auto()
Frequency = auto()
Length = auto()
# Etc ...
#]
Und dann eine zweite Aufzählungsklasse für die Einheiten (mit einigen Attributen, die später für die Konvertierung, das Parsen von Bearbeitungsfeldern in GUIs usw. verwendet werden):

Code: Select all

## --- Units
class Unit(Enum):
#[
## -- Definition
def __init__(self, metric: Metric, isSI: bool, scale: float, offset: float, symbols: set[str], isSpecialdB: bool = False):
#[
self.__metric = metric
self.__isSI = isSI
self.__scale = scale
self.__offset = offset
self.__symbols = symbols
self.__isSpecialdB = isSpecialdB
#]

## -- Make sure attributes are read only
@property
def Metric(self): return self.__metric
# ...
Wenn ich nun versuche, die verschiedenen Einheiten zu erstellen, verwechselt der Interpreter die Eigenschaft/Methode Metric (wird verwendet, um auf die zugehörige Metrik als schreibgeschützte Eigenschaft zu verweisen) und die Klasse/Aufzählung Metric selbst:

Code: Select all

# If I write this, the interpreter is confused between the class and the property 'Metric'
Once = (Metric.Mass, False, (0.45359237 / 16), 0.0, {'oz', 'once', 'onces'})
Ich habe zwei Lösungen gefunden, um diese Verwirrung zu vermeiden:
Entweder verwende ich globals(), um den Abgleich mit der Klassendefinition zu erzwingen:

Code: Select all

# Force to use 'class Metric'
Once = (globals()['Metric'].Mass, False, (0.45359237 / 16), 0.0, {'oz', 'once', 'onces'})
Entweder ist mir auch aufgefallen, dass ich einfach schreibgeschützte Eigenschaften definieren konnte, nachdem ich Aufzählungswerte definiert hatte:

Code: Select all

    ## -- Mass units
Kilogram = (Metric.Mass, True, 1.0, 0.0, {'kg', 'kilogram', 'kilograms'})
Gram = (Metric.Mass, False, 1.0e-3, 0.0, {'g', 'gram', 'grams'})
Pound = (Metric.Mass, False, 0.45359237, 0.0, {'lb', 'lbs', 'pound', 'pounds'})
Once = (Metric.Mass, False, (0.45359237 / 16), 0.0, {'oz', 'once', 'onces'})

## -- Etc units ...
# ....

## -- Make sure attributes are read only
## NEED TO BE DEFINED AFTER ENUMERATION VALUES TO AVOID CONFUSION WITH 'class Metric'
@property
def Metric(self): return self.__metric
# ...
#]
Obwohl ich Lösungen für mein Problem gefunden habe, aber da es auch fast mein erster Code in Python ist, frage ich mich, ob es eine bessere Lösung als globals() oder die richtige Reihenfolge der Codedefinitionen (nicht immer machbar) gibt, um auf eine bestimmte Klasse/Funktion im Code zu verweisen? Hier ist zum Beispiel ein weiterer Fall, in dem ich globals() verwenden musste, um auf eine gemeinsame Dienstprogrammfunktion aus zwei Klassen zu verweisen, die nicht offengelegt werden sollte (z. B. öffentlich oder „_“), weil dies unsinnig/nutzlos wäre für:

Code: Select all

class Foo1:
@staticmethod
def Dummy1(): return globals()['__commonInternalHelperFcn']()

## Second class
class Foo2:
@staticmethod
def Dummy2(): return globals()['__commonInternalHelperFcn']()

## Private
def __commonInternalHelperFcn(): return __answer()
def __answer(): return 42
PS: Ich weiß, dass es nicht sehr „pythonisch“ ist, private/schreibgeschützte Konstruktionen im Code zu haben, und die Leute verlassen sich sowieso lieber auf Konventionen ...

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post