Как явно ссылаться на функцию/класс в модуле Python, чтобы избежать конфликта именPython

Программы на Python
Ответить
Anonymous
 Как явно ссылаться на функцию/класс в модуле Python, чтобы избежать конфликта имен

Сообщение Anonymous »

Я пытаюсь создать небольшой модуль Python для преобразования одной единицы измерения в другую (из аналогичного кода, который у меня есть много лет в Matlab и который соответствует моим потребностям).
Таким образом, я создал первый класс перечисления для определения доступных показателей:

Код: Выделить всё

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

## --- Metrics
class Metric(Enum):
#[
DimensionLess = auto()
Mass = auto()
Frequency = auto()
Length = auto()
# Etc ...
#]
А затем второй класс перечисления для единиц измерения (с некоторыми атрибутами, которые позже будут использоваться для преобразования, анализа полей редактирования в графическом интерфейсе и т. д.):

Код: Выделить всё

## --- 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
# ...
Теперь, когда я пытаюсь создать различные единицы измерения, интерпретатор путается между свойством/методом Metric (используемым для ссылки на связанную метрику как свойство, доступное только для чтения) и самим классом/перечислением Metric:

Код: Выделить всё

# 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'})
Я нашел два решения, чтобы избежать этой путаницы:
Либо я использую globals() для принудительного сопоставления с определением класса:

Код: Выделить всё

# Force to use 'class Metric'
Once = (globals()['Metric'].Mass, False, (0.45359237 / 16), 0.0, {'oz', 'once', 'onces'})
Либо я также заметил, что могу просто определить свойства, доступные только для чтения, после определения значений перечисления:

Код: Выделить всё

    ## -- 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
# ...
#]
Хотя я нашел решения своей проблемы, но, поскольку это также почти мой первый код на Python, мне интересно, есть ли лучшее решение, чем globals() или правильное упорядочивание определений кода (не всегда осуществимо), чтобы ссылаться на конкретный класс/функцию в коде? Вот, например, еще один случай, когда мне пришлось использовать globals() для ссылки на общую служебную функцию из двух классов, которая не предназначалась для раскрытия (т.е. общедоступной или '_'), потому что это было бы бессмысленно/бесполезно для:

Код: Выделить всё

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: Я знаю, что это не очень «питонично» — иметь в коде частные конструкции/конструкции, доступные только для чтения, и люди в любом случае предпочитают полагаться на соглашения...


Подробнее здесь: https://stackoverflow.com/questions/798 ... d-naming-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»