Я просто поймал себя писать код так:Force подписи конкретных функций
def register(self, *, # * enforces keyword-only parameters
key_value_container:dict=None, # legal parameter set #1
key:str=None, value=None): # legal parameter set #2
# enforce one of the parameter sets
if not ((key_value_container is not None and
key is None and value is None) or
(key is not None and value is not None and
key_value_container is None)):
raise TypeError('provide (key_value_container) or (key/value')
# handle each legal parameter setf
if key_value_container is not None:
for _k, _s in key_value_container.items():
self.register(_k, _s)
else:
do_something_with(key, value)
Моя цель состояла в том, чтобы иметь две подписи метода register()
: он должен взять key
и или какой-то контейнер value
с рядом ключи и значения, например a dict
.
В *
в аргументе по крайней мере, заставляет меня представить именованные аргументы, но нет никакой необходимости, чтобы обеспечить заданное число аргументов или даже данный набор аргументов.
Конечно, я могу (должен) предоставить два метода с разными именами и сигнатурами вместо одного.
Но в случае, если я хочу (иметь) предоставить один метод/функцию с несколькими семантикой параметров - что является лучшим способом сделать это видимым и обеспечить его соблюдение?
Подробно:
- это можно сделать ясно автозавершения и документации которые являются комбинации правовых параметров?
- Как я могу проверить (с минимальным кодом шаблона), была ли предоставлена одна комбинация?
Итак, вы в основном хотите реализовать полиморфные методы в Python? – jonrsharpe
Мне было бы достаточно иметь элегантный способ проверить и сообщить некоторые ограничения. Python уже проверяет согласованность для случая, когда вы указываете * фиксированное число * аргументов (и оно также проверяет * максимальное количество аргументов). Но на самом деле это, по крайней мере, очень близко к полиморфным методам/функциям. – frans
Вы можете реализовать что-то с помощью декоратора, чтобы сделать это (отправка от одного имени до нескольких реализаций), но это, вероятно, не будет хорошо работать с автозаполнением и т. Д., Поскольку метод, который вы на самом деле вызываете, будет иметь произвольные '* args , ** интерфейс kwargs'. – jonrsharpe