2011-12-28 5 views
3

У меня есть набор переменных в Python, некоторые из которых являются нормальными номерами Python, а некоторые из них являются экземплярами класса, который я написал с именем Property, который представляет диапазон возможных значений (например, между 0 и 4.2). Я хочу перебирать эту коллекцию и делать что-то другое в зависимости от того, является ли каждый элемент встроенным номером или Property. Конечно, я мог бы сделать это, явно проверив тип, но я хочу знать, есть ли чистый, объектно-ориентированный идиоматический способ сделать это в Python.Полиморфизм со встроенными типами в Python

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

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

myList = [0, 2.3, 4, Property(0,2)] 

я должен был бы написать что-то вроде

myList = [Property(0), Property(2.3), Property(4), Property(0,2)] 

, который я предпочел бы избежать, если это возможно.

Вот еще информация о том, что я пытаюсь сделать. Я работаю над научной проблемой, которая включает в себя отслеживание множества переменных, которые в определенной степени взаимосвязаны. Многие из этих переменных имеют известные значения (поскольку они были измерены), но некоторые из них неизвестны, а другие были измерены, но не точно, поэтому мы знаем, что они должны лежать в определенном диапазоне. Существуют уравнения, которые определяют взаимосвязи между этими переменными, и в конечном итоге я буду использовать библиотеку численной оптимизации, чтобы найти возможные диапазоны неизвестных переменных.

Поскольку существует множество переменных, я хочу хранить все известные данные о них в формате с отформатированным форматированием. Хотя я хочу сохранить этот файл python для простоты, важно сохранить его синтаксис как можно более простым, как для меня, так и потому, что его могут читать или добавлять не-программисты. В настоящее время она имеет множество линий, которые выглядят что-то смутно, как это:

a.set_some_parameters(3.2, -1, Property(2.3,2.5)) 
a.x = 0.1 
b.x = Property.unknown() 
a.set_some_other_parameters(Property.positive(), -4.2, 1, 0) 

Дело в том, что (в значительной степени) в любом месте вы можете ввести номер, вы можете вместо этого ввести свойство, если значение точно не известно. Это хорошо работает как интерфейс, но я вхожу в ситуацию, описанную выше, где мой код постоянно должен иметь дело с тем, что что-то может быть встроенным числом, или может быть экземпляром Property.

+0

насчет подклассов некоторый класс от (http://docs.python.org/library/numbers.html) модуля [числа]? – brandizzi

+0

вы можете «попробовать: i.get_sign(), за исключением: ...» – jimifiki

ответ

1

Без достаточного знания о том, что вы делаете, я буду идти вперед и согласиться с вашим утверждением

Может быть, я просто сделать ошибку, имея коллекцию, которая смешивает экземпляры класса со встроенным -в типов

Если вам нужно только сравнить знак между встроенными номерами и экземплярам собственности, оно не будет таким большим делом (используйте функцию cmp и переопределять операторы сравнения на классе недвижимости) , но я уверен, что это еще не все, что вы хотите сделать.

Вместо этого подумайте о лучших способах создания своего списка, если это вас действительно беспокоит. Вот два примера:

P = Property 
myList = [P(0), P(2.3), P(4), P(0,2)] 

# or... 

def createPropertyList(*args): 
    return [Property(x) for x in args] 

myList = createPropertyList(0,2.3,4,(0,2)) 
+0

+1: «соглашайтесь с вашим заявлением». Да. Это эпически плохой дизайн, чтобы иметь коллекцию произвольных типов. –

+0

Возможно, вы правы. Тем не менее, я не вижу очень сжатого способа делать то, что я действительно хочу. Я добавил дополнительную информацию об этом в вопросе. Я не просто создаю один массив - это довольно сложный интерфейс, и я хочу, чтобы он был как можно более незаметным. – Nathaniel

+0

Конечно, я мог бы иметь биты кода по всему месту, которые проверяют тип переменных и преобразовывают их в свойства, если они являются числами, но затем я возвращаюсь к явной проверке типов. – Nathaniel

0

С точки зрения дизайна вы делаете что-то странное. Если у вас есть список вещей, и вы хотите действовать на них, они что-то разделяют!

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

У вас есть несколько различных решений:

их вы предлагаете вы могли бы определить новый конструктор для недвижимости, которая принимает встроенную,

-ели вы хотите, чтобы ваш объект все еще быть целым числом вы можете сделать подкласс целых чисел,

-Вы можете также определить новый класс, который имеет целочисленный член, тогда вы можете определить методы вашего нового класса, чтобы определить соответствующий интерфейс для вашего целого. Другими словами, вы переносите свое целое число в новый класс.

Пожалуйста, сделайте что-нибудь для получения соответствующего общего интерфейса для объектов в вашем списке.

Смежные вопросы