Думаю многие заглядывали в исходный код используемых библиотек, которые идут в дополнение Django и Django REST.
Вот, например, код настроек фреймворка Django REST, идущего в дополнение к Django.
class APISettings:
def __init__(self, user_settings=None, defaults=None, import_strings=None):
if user_settings:
self._user_settings = self.__check_user_settings(user_settings)
self.defaults = defaults or DEFAULTS
self.import_strings = import_strings or IMPORT_STRINGS
self._cached_attrs = set()
def __getattr__(self, attr):
if attr not in self.defaults:
raise AttributeError("Invalid API setting: '%s'" % attr)
try:
# Check if present in user settings
val = self.user_settings[attr]
except KeyError:
# Fall back to defaults
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr)
# Cache the result
self._cached_attrs.add(attr)
setattr(self, attr, val)
return val
Здесь, обращаясь к какому-либо атрибуту вызывается метод, импортирующий объект, располагающийся по строковому пути. Зачем каждый раз, когда будет осуществляться обращение к импортируемому атрибуту его импортировать? Нельзя сразу в методе init установить импортированную строку, чтобы потом каждый раз не приходилось производить операцию?
Может я неправильно понимаю, как работает этот метод? Вот если что код еще одного человека, использующего такой подход:
class NestedSettings:
def __init__(
self, user_settings, defaults, import_strings,
root_setting_name):
if user_settings:
self._user_settings = user_settings
self.defaults = defaults
self.import_strings = import_strings
self.root_setting_name = root_setting_name
def __getattr__(self, attr):
if attr not in self.defaults.keys():
raise AttributeError(
"Invalid {self.root_setting_name} setting: '{attr}'".format(
self=self, attr=attr))
try:
# Check if present in user settings
val = self.user_settings[attr]
except KeyError:
# Fall back to defaults
val = self.defaults[attr]
# Coerce import strings into classes
if attr in self.import_strings:
val = perform_import(val, attr)
# Cache the result
setattr(self, attr, val)
return val
Код, как можете заметить, не сильно отличается.
P.S перечислены не все методы классов, если нужен фулл код, то вот ссылки:
https://github.com/apragacz/django-rest-registrati...
https://github.com/encode/django-rest-framework/bl...