Я хочу дать пользователю API для моей библиотеки с более простым способом различать различные типы параметров, которые я передаю функции. Все группы аргументов определены раньше (на данный момент у меня есть 3 группы), но атрибуты из них должны быть построены при запуске. Я могу сделать это в стиле Django ORM, где двойной подчеркивание разделяет 2 части параметра. Но это очень непроницаемо. Пример:Магическое назначение для настраиваемых параметров
def api_function(**kwargs):
""" Separate passed arguments """
api_function(post__arg1='foo', api__arg1='bar', post_arg2='foo2')
Лучший способ сделать это SQLAlchemy, но только для сравнения атрибутов и все арги определены ранее. Пример:
class API(object):
arg1 = Arg()
arg2 = Arg()
class Post(object): #...
def api_function(*args):
""" Separate passed arguments """
api_function(POST.arg1=='foo', API.arg1=='bar', POST.arg2=='foo2')
То, что я хотел бы для того чтобы достигнуть это поведение, как это:
class API(object): # Magic
class POST(object): # Magic
def api_function(*args):
""" Separate passed arguments """
api_function(POST.arg1='foo', API.arg1='bar', POST.arg2='foo2')
Что я пробовал:
- объявлять метамодель с определенным
__setattr__
, но подняться по оценкеSyntaxError: keyword can't be an expression
- Объявление
__set__
, но оно предназначено для известных атрибутов
Мои вопросы:
- Возможно ли это в Python, чтобы работать, как в третьем фрагменте?
- Если нет, есть ли действительно очень близкое решение в третьем фрагменте? Лучший способ следует использовать оператор присваивания
API.arg1='foo'
, худшийAPI(arg1='foo')
Требования - должны работать по крайней мере на Python 2.7. Хорошо работать на Python 3.2.
EDIT1 Мой первый тест, который использует оператор равенства (но никогда не должны быть использованы таким образом):
class APIMeta(type):
def __getattr__(cls, item):
return ApiData(item, None)
class API(object):
__metaclass__ = APIMeta
def __init__(self, key, value):
self.key = key
self.value = value
def __str__(self):
return "{0}={1}".format(self.key, self.value)
def __eq__(self, other):
self.value = other
return self
def print_api(*api_data):
for a in api_data:
print(str(a))
print_api(API.page=='3', API=='bar')
Это работает правильно, но с использованием ==
предполагает, что я хочу что-то сравнить, и я хочу присвоить значение.
Что не так с 'api_function (POST = dict (arg1 = 'foo', arg2 = 'foo2'), API = dict (arg1 = 'bar'))'? – Eevee
Потому что я мог бы использовать 'api_function (POST (arg1 = 'foo', arg2 = 'foo2'), API (arg1 = 'bar'))', что является более читаемым, более коротким и более логичным решением. Но я пытаюсь сделать эту библиотеку наиболее простой для чтения для людей. – zwierzak
@zwierzak Нет никакого способа сделать это, как в третьем фрагменте. Переменные не могут иметь '.' В их имени. Тем не менее, другой способ определенно выполним в зависимости от того, как вы ожидаете получить доступ к аргументам в 'api_function'. – mr2ert