Вам не нужно беспокоиться об именах файлов, содержащих нулевые байты в Unixes и Windows, потому что они не могут.
Однако имена файлов, которые обрабатываются как UTF-8, могут указывать символ NUL (U + 0000) с использованием недопустимых «чрезмерно длинных» последовательностей: двух, трех или четырехбайтовых последовательностей UTF-8, которые имеют все нули в своих биты полезной нагрузки кодовой точки.
Это может быть проблемой безопасности. Например, декодер UTF-8, который не проверяет это, может в конечном итоге генерировать значение символа wchar_t
, равное 0, которое затем неожиданно завершает строку широких символов.
Например, последовательность байтов C0 80 является слишком длинным кодированием для NUL. Это, очевидно, используется неким thign, называемым «Modified UTF-8», специально для целей кодирования символов NUL, которые не заканчивают строку C, используемую для хранения UTF-8.
Если вы проводите тестирование безопасности, это актуально; Вы можете проверить, восприимчивы ли программы к введению символов NUL (и других) через слишком длинные кодировки.
Это также работает с вложенным dicts и удостоверяется, что dicts, которые добавляются позже, ведут себя то же:
class DotDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Recursively turn nested dicts into DotDicts
for key, value in self.items():
if type(value) is dict:
self[key] = DotDict(value)
def __setitem__(self, key, item):
if type(item) is dict:
item = DotDict(item)
super().__setitem__(key, item)
__setattr__ = __setitem__
__getattr__ = dict.__getitem__
Я недавно столкнулся с библиотекой 'Box', которая делает то же самое.
from box import Box
mydict = {"key1":{"v1":0.375,
"v2":0.625},
"key2":0.125,
}
mydict = Box(mydict)
print(mydict.key1.v1)
я нашел, что это было более эффективным, чем другие существующие библиотеки как dotmap, которые генерируют ошибку рекурсии Python, когда Вы имеете большой, вложил dicts.
ответ @derek73 очень аккуратен, но он не может быть соле, ни (глубоко) скопирован, и он возвращается None
для недостающих ключей. Код ниже мер это.
Редактирование: я не видел ответ выше , который обращается к той же самой точке (upvoted). Я оставляю ответ здесь для ссылки.
class dotdict(dict):
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
Получите из dict и реализуйте __ getattr __
и __ setattr __
.
Или вы можете использовать Bunch , что очень похоже.
Я не думаю, что можно запрограммировать встроенный dict-класс monkeypatch.
Не надо. Доступ к атрибутам и индексирование - это разные вещи в Python, и вы не должны желать, чтобы они выполняли одно и то же. Создайте класс (возможно, созданный namedtuple
), если у вас есть что-то, что должно иметь доступные атрибуты, и используйте нотацию []
, чтобы получить элемент из dict.