В моем ответе я расскажу о разработке API-интерфейсов для использования dicts и args-ключевых слов.
Но также применимо индивидуальное использование {...}
против dict(...)
.
Суть: будьте последовательны. Если большая часть вашего кода будет ссылаться на 'bar'
как на строку - оставьте строку в {...}
; если вы обычно ссылаетесь на него, идентификатор bar
- используйте dict(bar=...)
.
Ограничения
Прежде чем говорить о стиле, обратите внимание, что синтаксис ключевого слова bar=42
работает только для строк и только в том случае, если они являются допустимыми идентификаторами. Если вам нужны произвольные знаки препинания, пробелы, Unicode - или даже не строковые ключи - вопрос закончен => будет работать только синтаксис {'bar': 42}
.
Это также означает, что при разработке API вы должны разрешать полные диктовки, а не только аргументы ключевых слов - если вы не уверены, что разрешены только строки и только допустимые идентификаторы.
(Технически, update(**{'spaces & punctuation': 42})
работает. Но это уродливо. И числа / кортежи / юникод не будут работать.)
Обратите внимание, что dict()
и dict.update()
объединяют оба API: вы можете передать один диктовку, вы можете передать аргументы ключевых слов, и вы можете даже передать оба (позже, я думаю, без документов). Поэтому, если вы хотите быть милым, позвольте оба:
def update(self, *args, **kwargs):
"""Callable as dict() - with either a mapping or keyword args:
.update(mapping)
.update(**kwargs)
"""
mapping = dict(*args, **kwargs)
# do something with `mapping`...
Это особенно рекомендуется для метода с именем .update()
, который следует правилу наименьшего сюрприза.
Style
Мне приятно отличать внутренние от внешних строк. Под внутренним я подразумеваю произвольные идентификаторы, обозначающие что-то только внутри программы (имена переменных, атрибуты объектов) или, возможно, между несколькими программами (столбцы БД, имена атрибутов XML). Обычно они видны только разработчикам. Внешние струны предназначены для потребления человеком.
[Некоторые кодеры Python (включая меня) соблюдают соглашение об использовании 'single_quotes'
для внутренних строк против "Double quotes"
для внешних строк. Хотя это определенно не универсально.]
Ваш вопрос касается правильного использования barewords (термин Perl) - синтаксических сахаров, позволяющих полностью исключить кавычки во внутренних строках. Некоторые языки (особенно LISP) позволяют им широко; Питонские возможности использовать голые слова - это атрибут доступа - foo.bar
и ключевые аргументы - update(bar=...)
.
Стилистическая дилемма здесь " Достаточно ли внутренняя строка для того, чтобы выглядеть как идентификаторы? "
Если ключи являются внешними строками, ответ определенно НЕТ:
foo.update({"The answer to the big question": 42})
# which you later might access as:
foo["The answer to the big question"]
Если ключи ссылаются на идентификаторы Python (например, атрибуты объекта), тогда я скажу ДА:
foo.update(dict(bar=42))
# As others mentioned, in that case the cleaner API (if possible)
# would be to receive them as **kwargs directly:
foo.update(bar=42)
# which you later might access as:
foo.bar
Если ключи ссылаются на идентификаторы вне вашей программы на Python, такие как имена атрибутов XML или имена столбцов БД, использование голых слов может быть хорошим или плохим выбором - но вам лучше выбрать один стиль и быть согласованным .
Согласованность хорошая, потому что между идентификаторами и строками существует психологический барьер. Он существует, потому что строки редко пересекают его - только при использовании интроспекции для выполнения метапрограммирования. И подсветка синтаксиса только усиливает это. Поэтому, если вы прочитаете код и увидите зеленое 'bar'
в одном месте и черное foo.bar
во втором месте, вы не сможете сразу установить соединение.
Еще одно важное правило: Голые слова хороши, если они (в основном) исправлены . Например. если вы ссылаетесь на фиксированные столбцы БД в основном в своем коде, тогда использование голых слов для ссылки на них было бы неплохо; но если в половине случаев столбец является параметром, то лучше использовать строки.
Это потому, что параметр / константа - это самое важное различие, которое люди связывают с барьером идентификаторов / строк. Разница между column
(переменная) и "person"
(постоянная) является наиболее читаемым способом передачи этой разницы. Создание обоих идентификаторов приведет к размыванию различий, а также к синтаксическому обратному эффекту - вам придется много использовать **{column: value}
и getattr(obj, column)
и т. Д.