Я думаю, что это немного обманчивый пример;есть то, что вы не заявили.Я предполагаю, что когда вы говорите, что у вас «есть интерфейс», вы имеете в виду, что у вас есть код, который принимает объект и вызывает его метод run
.
Если вы не проверяете тип этого объекта перед вызовом его метода run
, то вы используете простую и понятную типизацию утиной команды!(В этом случае, если у него есть метод run
, то это Runner
.) Пока вы не используете type
или isinstance
для объекта с методом run
, тогда вы 'ты пифоник.
Вопрос о том, должны ли вы принимать простые строки или только объекты узлов, является немного другим вопросом.Строки и объекты node
, вероятно, вообще не реализуют один и тот же интерфейс!Струны в основном не крякают как node
, поэтому вам не нужно обращаться с ними как с одним.Это как слон, который приходит вместе, и если вы хотите, чтобы он крякал как утка, вы должны дать слону магнитофон и приучить слона использовать его первым.
Так что это уже не вопрос «утки», а дизайн интерфейса.Вы пытаетесь решить, насколько строгим должен быть ваш интерфейс.
Чтобы дать вам ответ, тогда на этом уровне, я думаю, наиболее питонично предположить, что run
возвращает объект node
.Для этого не нужно использовать isinstance
или type
.Просто представьте, что это объект node
, и если программист, использующий ваш интерфейс, поймет это неправильно и увидит исключение, ему придется прочитать вашу строку документации, которая скажет им, что run
должен передать объект node
.
Тогда, если вы хотите, чтобы также принимал строки или вещи, которые крякают как строки, вы можете сделать это.И поскольку строки являются довольно примитивными типами, я бы сказал, что не следует использовать isinstance(obj, basestring)
(но не type(obj) == str
, потому что это отклоняет строки в юникоде и т. Д.).По сути, вы очень либеральны и добры к ленивым пользователям вашей программы;Вы уже делаете все возможное, принимая слонов, а также вещи, которые крякают, как утки.
(Более конкретно, я бы сказал, что это немного похоже на вызов iter
для аргумента в начале функции, которую вы хотите принять как генераторы, так и последовательности.)