Найти - Пользователи
Полная версия: PEP8 и аттрибуты класса
Начало » Python для экспертов » PEP8 и аттрибуты класса
1 2
Master_Sergius
Здравствуйте,

Некая API возвращает ответы в json-формате, где имена переменных в lowerCamelCase:
 {"userId": "xxx", "firstName": "John", "lastName": "Connor"}

Ну и кто-то когда-то решил сделать представление модели такого user-a в “pythonic-way”, то есть все параметры в snake_case:
  
class User:
    first_name = None
    last_name = None

Естественно, для ответ от API приводят к snake_case виду, что уже немного нехорошо. И вот настоящие проблемы появляются, когда оказывается, что на стороне сервера, можно создать юзера з такими параметрами (то есть, кроме базового набора параметров, можно добавлять еще и пользовательские параметры):
 {"userId": "xxx", "firstName": "John", "first_name": "Jonny", "lastName": "Connor"}
Да, это тупо, но, возможно. Я предложил лиду решение - не делать это в pythonic-way, то есть не менять регистр переменных, пусть как приходят, так и будут в модели отображатся, а для обратной совместимости, пропишем __getattr__/__setattr__, чтобы пытаться найти имена в другом регистре. Но, лид говорит - никак нет, это не pythonic-way.

Но, вроде же, это можно, даже с учетом самого PEP8 - https://www.python.org/dev/peps/pep-0008/#function-and-variable-names (mixedCase). И что делать? Я прав/не прав? Как переубедить лида?
PEHDOM
Master_Sergius по моему это идиотизм, не стоит вопринимать pythonic-way как какуюто догму.
Если вам приходят данные в mixedCase то так их и обрабтывайте, ничего особо криминального в этом нет. Никто вас не расстреляет за это.. ИМХО
как говорил Джек Воробей, кодекс PEP8 это скорее руководство к действию, а не свод строгих правил.

Master_Sergius
Но, вроде же, это можно, даже с учетом самого PEP8
Ну там чутка про иное, что типо можно если уже такое используется, чтобы не нарушать преобладающий стиль.
doza_and
Помоему Pep8 касается имен переменных а никак не данных.

Если ключей 3 как в примере, то не так уж сложно привести к snake case. И я бы поддержал вашего тим лида, чтобы 3 переменные не были белыми воронами.

Но конечно бывают случаи когда переменных много и есть пользователи которые привыкли к их предопределенному виду. Тогда очевидно надо пользоваться как есть.

Например у нас питон используется как скриптовая часть к некой сложной модели. Там принято имена давать upper case и всего имен порядка двух миллионов. Понятно что используются имена предметной области.
py.user.next
Master_Sergius
Ну и кто-то когда-то решил сделать представление модели такого user-a в “pythonic-way”, то есть все параметры в snake_case:
Ну, всё правильно.

Master_Sergius
Естественно, для ответ от API приводят к snake_case виду, что уже немного нехорошо.
Так ты должен преобразовать их дальше. Если у тебя появляется тупорылый API, то это не значит, что ты свой код за ним следом должен делать тупорылым. У тебя должны быть преобразователи туда и обратно. Ещё много таких ситуаций будет. Что, под каждый отдельный API будешь код менять? А когда разные API начнут другу противоречить и склэшатся, что ты тогда будешь делать? Вообще программу писать перестанешь? Поэтому делай адаптеры на вход и на выход. А код держи в чистоте со всеми правилами.

Master_Sergius
Я прав/не прав?
Конечно, не прав. Выброси ещё все линтеры, они же тоже пишут, что у тебя всё неправильно. Но, я думаю, ты ими просто не пользуешься ещё.
AD0DE412
Master_Sergius
настоящие проблемы появляются, когда оказывается
ок префикс + ваша змеюка … а не … хм

ну тогогда нужно выходить из этой системы вернее стать над ней
нужно подорбрать какие то другие основания (не знаю индекс, uuid, время …) для периименования или оставить все как есть
Master_Sergius
py.user.next
Выброси ещё все линтеры, они же тоже пишут, что у тебя всё неправильно. Но, я думаю, ты ими просто не пользуешься ещё.
Зачем сразу бросаться оскорблениями, товарищ? Я пользовался линтерами “ещё до того, как это стало мейнстримом”. Тут дело в другом, позвольте мне описать более подробно всю суть проблемы и крик души моей.

Есть некий сервис, назовём его GroupsAndUsers: он позволяет создавать группы пользователей, которые принадлежат той или иной группе, соответсвенно, могут залогиниться туда или туда, и имею права делать то, или другое. На UI этого сервиса админы групп могут изменять профили пользователей, а именно добавлять/удалять какие-то кастомные аттрибуты. Базовые аттрибуты типа firstName, lastName, email и т.д. - всегда остаются неизменными. Так вот, этот сервис позволяет назвать аттрибут как угодно, нет ограничений на snake_case, camelCase, UPPERCASE и т.д. API возвращает все как есть, не изменяя регистра. Через API можно получить юзера, можно и апдейтнуть, можно и удалить.

И есть вот python sdk, назовём его GroupsAndUsers SDK, наряду с другими sdk (Java, Go и т.д.), в которых никто регистры не меняет, и всё хорошо. Да и вообще, в теории все sdk для одного сервиса должны вести себя одинаково. Ну, допустим, как обычно обстоит дело в python sdk:
  
users = group_and_users_client.list_users()
# сырой ответ от API: [{"userId": "xxx", "firstName": "John", "lastName": "Connor"}]
# в переменной users будет список объектов типа User такого вида:
for user in users:
     print(user.first_name)
     print(user.last_name)

Если надо апдейтнуть юзера, всё просто:
  
user.first_name = "Sarah"
result = group_and_users_client.update_user(user_id=user.user_id, user)

Может быть просто маппинг базовых параметров, а можно и просто делать “case casting”, что в принципе и было реализовано: автоматически переводить в snake_case результат и обратно в lowerCamelCase перед отправкой запроса.
А что получается, если кто-то создал кастомный аттрибут такого вида: FloorNumber: в snake_case он переводится, как floor_number, но обратно уже как floorNumber, то есть отличается первая буква и все, юзера апдейтнуть не получится.
Решение? Не переводить регистр для кастомных аттрибутов - ну такое себе:
  
user.first_name = "Sarah"
user.FloorNumber = 5
result = group_and_users_client.update_user(user_id=user.user_id, user)

Да и дальше получаются костыли на костыле, это ведь не последняя проблема, никогда не бывает последней…

PEHDOM
Master_Sergius ну тут нужно смотреть для чего и как у вас используется представление модели.
Вы вполне логично представили закономерную ситуацию что ктото заведет кастомный атрибут “floor_number” и тогда “case casting” сломается. Это реальная дыра в системе(допустим ктото заведет кастомный артибут user_іd) и оно может поломать вышестоящую систему.
Давайте я вам добавлю еще один кейс: завтра АПИ поменяется и будет возвращать данные в виде: {“UserId”: “xxx”, “FirstName”: “John”, “LastName”: “Connor”…} вам тогда что всю программу переписывать?
Очевидно мухи долнжы быть отдельно, а котлеты отдельно. Тоесть у вас должен быть конектор который будет делать маппинг базовых параметров в обе стороны и если АПИ поменяется то вам придется переписать только конектор. Но вы не можете предсказать в каком виде будут кастомные парметры и перводить их в lower_case_with_underscores или в какойто иной вид верх идиотизма. Они должны храниться отдельно “как есть”, чтобы вы четко понимали где у вас обязательные атрибуты, а где пользовательские, и в таком же виде обрабатываться/отдаваться в каком и приходят.
Rodegast
> Да, это тупо, но, возможно. … Но, лид говорит - никак нет, это не pythonic-way.

Для вас регистр букв такая большая проблема? Вам самим то не стыдно?

> На UI этого сервиса админы групп могут изменять профили пользователей, а именно добавлять/удалять какие-то кастомные аттрибуты

Каждый раз как админы что то поменяют вы модель обновляйте? Ну это вообще бред.
Master_Sergius
PEHDOM, сейчас оно так приблизительно и работает - кастомные атрибуты обрабатываются отдельно. Но выглядит это же очень некрасиво, как в примере выше.

Rodegast
Для вас регистр букв такая большая проблема? Вам самим то не стыдно?.

Нет, не стыдно Потому что, как я уже описал выше - есть исключения: 1) кто-то создаст кастомные атрибуты, которые в приведение в один регистр будут одинаковы; 2) кто-то создаст атрибут, который будет такой же как базовый, после приведения в один регистр. Это, конечно, крайне маловероятно, но возможно. Я бы не хотел, чтобы такая дырка оставалась. И, возможно, есть ещё какие-то случаи, о которых пока никто не догадывается, но пользователи всегда попадают на какие-то новые грабли.

Rodegast
Каждый раз как админы что то поменяют вы модель обновляйте? Ну это вообще бред.
Нет, конечно, модель формируется динамически.

Вот реально, разве не выглядит это все как костыль на костыле?
PEHDOM
Master_Sergius
Нет, конечно, модель формируется динамически.
Если модель формируется динамически то какая вам разница какими буквами там что заведено и что там внутри?
“pythonic-way” это в первую очередь для исходников, чтобы другим людям было удобнее/проще потом читать чужой код.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB