Проверка типа Python и проблема наследования - PullRequest
2 голосов
/ 19 мая 2010

У меня есть немного кода Python, который зависит от проверки типа. Я постараюсь сформулировать мою проблему на языке математики, чтобы она была понятна. У меня есть несколько классов, которые соответствуют подмножествам друг друга и образуют цепочку наследования.

class Real(object):
    pass

class Integer(Real):
    pass

class Natural(Integer):
    pass

И у меня есть кортежи, содержащие типы. Каждый из них соответствует области некоторой функции.

t1 = ( Real, Real )
t2 = ( Real , Integer )

Я хотел бы выполнить некоторую форму проверки типа, чтобы при наличии другого кортежа ( Natural , Natural ), если каждая координата в кортеже является подклассом указанных доменов. Например, для некоторой функции getcompatibles я бы хотел получить:

getcompatibles( ( Real, Real ) ) = [ t1 ]
getcompatibles( ( Real, Integer ) ) = [ t1, t2 ]
getcompatibles( ( Natural, Natural ) ) = [ t1, t2 ]
getcompatibles( ( Natural, Real ) ) = [ t1 ]

Единственное решение, которое я мог бы придумать, состоит в том, чтобы пройти через каждый домен for (t1, t2), проходящий через каждый из типов в __subclasses__, и проверить, является ли оно isinstance Истиной для заданного ввода.

Это крайне неэффективно, возможно, есть ли более питонский способ сделать это?

Ответы [ 2 ]

4 голосов
/ 19 мая 2010
def compatible_pred(obj_types, fun_signature):
  if len(obj_types) != len(fun_signature): return False
  return all(issubclass(of, ft) for of, ft in zip(obj_types, fun_signature))

def is_compatible(obj_types, fun_signatures=(t1, t2)):
  return [t for t in fun_signatures if compatible_pred(obj_types, t)]

Имя is_compatible для чего-то, что не предикат, действительно, по-настоящему сбивает с толку: почему бы не дать ему разумное имя, такое как getcompatibles, чтобы сильно звучащий предикат iscompatible может быть использовано вместо того, что я должен был назвать compatible_pred?

1 голос
/ 19 мая 2010

Не проверяйте типы, когда вам не нужно, и рассчитывайте на обработку исключений - с помощью try / except выявляйте случаи, когда ожидание нарушается.

В Python, который является языком с «ленивым типом» (но строго типизированным, меньше я расстраиваю пуристов), многократный вызов isinstance, безусловно, будет стоить вам лишних затрат. Когда я сталкиваюсь с такими вопросами о дизайне, я задаю себе вопрос: «Если вы не хотите, чтобы эта функция обрабатывала пары Naturals, почему вы вызывали ее вместе с ними?» Предположительно, вы выполняете некую условную ветвь, основанную на is_compatible, я бы посоветовал вам изменить это на условный вызов.

Просмотр того, как вы намереваетесь использовать результат is_compatible, позволит получить более сфокусированный ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...