** kwargs против 10 аргументов в функции Python?

Я начинаю с Python и пытаюсь создать XML-запрос для веб-сервис ebay:

Теперь мой вопрос:

Скажем, это моя функция:

def findBestMatchItemDetailsAcrossStores():
     request = """<?xml version="1.0" encoding="utf-8"?>
     <findBestMatchItemDetailsAcrossStoresRequest xmlns="http://www.ebay.com/marketplace/search/v1/services">
     <siteResultsPerPage>50</siteResultsPerPage>
     <entriesPerPage>50</entriesPerPage>
     <ignoreFeatured>true</ignoreFeatured>
     <keywords>ipod</keywords> <-----REQUIRED
     <itemFilter>
     <paramName>PriceMin</paramName>
     <paramValue>50</paramValue>
     <name>Currency</name>
     <value>USD</value>
     </itemFilter>
     <itemFilter>
     <paramName>PriceMax</paramName>
     <paramValue>100</paramValue>
     </itemFilter>
     </findBestMatchItemDetailsAcrossStoresRequest>"""
     return get_response(findBestMatchItemDetailsAcrossStores.__name__, request)

Где, ключевое слово является единственным обязательным полем. Итак, как мне построить метод? Способы могут быть:

  1. Создайте объект, передайте его функции (объекту): способ Java
  2. Передать все аргументы: func(a=val1, b=val2, c=val3, d=val4 и т. д.)
  3. Используйте **kwargs и доверяйте тому, кто вызывает функцию, что он передает правильные ключи со значениями, потому что я буду использовать ключи для фактического построения XML-тегов.

Обновление:

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

Какие-либо предложения?


person zengr    schedule 03.06.2011    source источник
comment
Какие поля должны иметь возможность изменять другие функции?   -  person Nick ODell    schedule 03.06.2011
comment
не понял. все эти поля являются локальными только для этой функции.   -  person zengr    schedule 03.06.2011
comment
Другими словами, какие поля программа должна указать на лету?   -  person Nick ODell    schedule 03.06.2011
comment
Ну и все изверги в строке запроса должны передаваться пользователем метода. Единственная разница в том, что все поля являются необязательными, кроме <keywords>ipod</keywords>, которое является обязательным.   -  person zengr    schedule 03.06.2011
comment
Я думаю, что это случай явного лучше   -  person John La Rooy    schedule 03.06.2011
comment
@gnibbler Итак, в таком случае: как мне построить строку? проверить и добавить?   -  person zengr    schedule 03.06.2011


Ответы (3)


Хорошая идея — поместить все параметры с соответствующими значениями по умолчанию (или только None значений по умолчанию) в сигнатуру функции. Да, это потребует немного больше ввода самой функции, но интерфейс будет чистым, самодокументированным и простым в использовании, так как вам не придется искать возможные параметры в документах ebay или источнике функции. В дальнейшем это сэкономит вам время.

person letitbee    schedule 03.06.2011
comment
да, я тоже за такой подход, т.е. подход 2. - person zengr; 03.06.2011
comment
Соглашаться. **kwargs в первую очередь полезно, когда вы заранее не знаете, какие имена аргументов вы ожидаете (см., например, str.format). Если вы ожидаете определенных аргументов, лучше указать их явно. - person lvc; 03.06.2011

как насчет моделирования сообщения как класса?

class FindBestMatchItemDetailsAcrossStoresRequest:
     def __init__(self,keywords):
         self.keywords = keywords # required parameters in the constructor
         # set up the default values....etc
         self.siteResultsPerPage = 50 
         self.name = 'Currency'


     def send(self):
         # build message from self.xxx
         return get_response()


 #usage
 req = FindBestMatchItemDetailsAcrossStoresRequest('ipod')
 response = req.send()

 #usage with optional args

 req.siteResultsPerPage = 150
 response = req.send()
person Gareth Davis    schedule 03.06.2011
comment
Я тоже хотел бы знать, мне это кажется хорошим. Но я не знаю о питонических способах. - person zengr; 03.06.2011
comment
Предположительно, вы имели в виду req = FindBestMatchItemDetailsAcrossStoresRequest('ipod')? - person Johnsyweb; 03.06.2011
comment
обновил мой вопрос. Я думаю, вы неправильно поняли мой вопрос. В этом случае, что если пользователь захочет пройти: siteResultsPerPage? как я этого добьюсь? - person zengr; 03.06.2011
comment
@Johnsyweb Это вызовет TypeError, так как Гарет забыл self. Кроме того, я не вижу смысла использовать класс, скажем, вместо defaultdict. - person letitbee; 03.06.2011

Я бы использовал именованные параметры для всех. Делая это, очень легко назначать значения по умолчанию и заставлять пользователя указывать требуемые параметры (путем исключения значения по умолчанию).

person circus    schedule 03.06.2011