Форум сайта python.su
Здравствуйте, мне понравилось обсуждение моего предыдущего дурацкого вопроса http://python.su/forum/topic/40304/, и я решил замутить еще одно
Начнем с сути проблемы: есть апишка (всё та же, но не суть), все ответы которой представляются в сдк как объекты/модели (можно сказать, аналог ORM):
class User: first_name = None last_name = None position = None users = group_and_users_client.list_users() # сырой ответ от API: [{"userId": "xxx", "firstName": "John", "lastName": "Connor", "position": "Tester"}] # в переменной users будет список объектов типа User такого вида: for user in users: print(user.first_name, user.last_name, user.position)
from aenum import Enum, extend_enum class Position( str, Enum ): DEV = "DEV" TESTER = "TESTER" MANAGER = "MANAGER" @classmethod def _missing_(cls, value): value_upper_case = value.upper() try: return getattr(cls, value_upper_case) except: extend_enum(Position, value_upper_case, value_upper_case) return getattr(cls, value_upper_case)
class Dev(User): position = 'DEV' class Tester(User): position = 'TESTER' class MANAGER(User): position = 'MANAGER'
for user in users: print(user.position, type(user.position)) # выхлоп (AQA - Automation QA): DEV <class 'str'> TESTER <class 'str'> Position.AQA <aenum 'Position'>
if isinstance(user.position, str): print(user.position) else: print(user.position.value) # или наоборот if isinstance(user.position, Position): print(user.position.value) else: print(user.position)
class PositionWrapper(str): def __new__(cls, position): if isinstance(position, Enum): return str.__new__(cls, position.value) return str.__new__(cls, position) def __init__(self, position): self.position = position def __str__(self): return self.value @property def value(self): if isinstance(self.position, Enum): return self.position.value return self.position
File "/Users/bserhii/Projects/work/okta/venv/lib/python3.8/site-packages/aenum/__init__.py", line 1638, in __prepare__ member_type, first_enum = metacls._get_mixins_(bases) File "/Users/bserhii/Projects/work/okta/venv/lib/python3.8/site-packages/aenum/__init__.py", line 2263, in _get_mixins_ raise TypeError("cannot extend enumerations via subclassing") TypeError: cannot extend enumerations via subclassing
Отредактировано Master_Sergius (Май 21, 2021 20:13:35)
Офлайн
кхм кхм эээ ок enum неизменяемый но вам нужно сделать его ну или что бы это походило на “изменяемый” enum так?
и второе без изменений в существующем коде (новый добавить можно)
Отредактировано AD0DE412 (Май 21, 2021 21:28:47)
Офлайн
Мне нужно сделать, чтобы:
1)
Вместо такого:
for user in users: print(user.position) # выхлоп (AQA - Automation QA): DEV <class 'str'> TESTER <class 'str'> Position.AQA <aenum 'Position'>
for user in users: print(user.position) # выхлоп (AQA - Automation QA): DEV <class 'str'> TESTER <class 'str'> AQA <class 'str'>
Офлайн
John Crawford 13 Мар 2019 в 20:00 ?
зы хотя скоре всего нет
наверное вы уже прошерстили че как и где в этих интернетах
Отредактировано AD0DE412 (Май 21, 2021 21:32:17)
Офлайн
Не уверен, что это поможет, разве что переписать по-другому класс Position и тогда плясать оттуда.
Даже не знаю, как без “breaking change” чтоб для “старых” пользователей нашей SDK работало это:
for user in users: if isinstance(user.position, str): print(user.position) else: print(user.position.value) # или наоборот for user in users: if isinstance(user.position, Position): print(user.position.value) else: print(user.position)
for user in users: print(user.position)
Офлайн
ну там вроде уникальность теряетсявернее ... объекты эээ исходные и то что получилось не true
Отредактировано AD0DE412 (Май 21, 2021 21:55:52)
Офлайн
> В общем, что делать?
Нормально проектировать программу, а не заниматься ерундой. У тебя position должен быть перечислением. Множественное наследование из класса Position нужно удалить и всё отрефакторить.
Офлайн
Rodegast ну так там у нее/него там ситуация
Офлайн
AD0DE412Ну так а некоторые высочайшим указом повелевают числу пи стать равным трем. Посылать надо “насяльнике ” вот и все.
ну так там у нее/него там ситуация
Master_Sergius
но насяльнике хочет, чтоб без “breaking change”
Master_Sergiusстранное у вас понимание “breaking change”. “breaking change” Это когда нарушаются соглашения декларируемые в документации к продукту. Для нормальных продуктов это означает что новая версия продукта перестала проходить тесты.
что вдруг кто-то решал для себя проблему таким образом….
Офлайн
> ну так там у нее/него там ситуация
А почему у него такая ситуация? Да потому что “наша sdk возвращает несовместимые типы позиций”. В место того что бы исправить ошибку и возвращать данные одного типа они предложили её костылём закрыть, а теперь при помощи другого костыля они этот костыль чинят.
С таким подходом “ситуации” для них уже должны быть нормой.
Офлайн