Найти - Пользователи
Полная версия: Множественные конструкторы (?)
Начало » Python для новичков » Множественные конструкторы (?)
1
Dmitrij
Прошу совета, как лучше сделать:

требуется создать объект, состоящий из нескольких полей:
а) w - список чисел
б) f - некоторая функция (например, синус)

Хитрость в том, что объект может быть инициализирован несколькими разными способами:

1) В конструктор передается функция f и число - длина списка, в результате генерируется объект, у которого список w заполнен нулями. Это я мог бы реализовать как-то так:
class A(object):
__init__(self, n, f):
self.f = f
self.w = [0.0]*n
...
2) В конструктор передается функция f и список w:
class A(object):
__init__(self, w, f):
self.f = f
self.w = w
...
3) В конструктор передается текстовое описание объекта: s="{'f': sin(), ‘w’: }"
class A(object):
__init__(self, s):
data = eval(s)
self.f = data['f']
self.w = data['w']
...
Таким образом, один и тот же класс должен иметь три разных конструктора, в зависимости от того, в каком виде приходят исходные данные. При этом, хочется иметь возможность создания объектов в единообразном виде (без предварительной обработки аргументов и приведения их к единообразному виду), т.е.:
a1 = A(10,cos())
a2 = A([1,1,2,0],sin())
a3 = A("{'f': cos(), 'w': [0,0,1]}")
Вопрос: есть ли какая-нибудь возможность объединить эти три вызова в один конструктор? Или же так вообще не делают, и я излишне мудрствую?
igor.kaist
А если просто типы проверять, и действовать уже согласно ситуации? Или я чего то недопонял…
P.S. вот, пару способов проверить тип переменной, если затруднения в этом…
Dmitrij
Спасибо за совет и ссылку. Но, собственно, исходный вопрос у меня был немного шире (каюсь, нечетко его сформулировал).

Я хотел узнать, есть ли какие-нибудь стандартные приемы, используемые в подобных ситуациях, ведь наверное, я не единственный, кто столкнулся с такой необходимостью? Один вариант подсказали - проверить типы входных параметров, есть ли еще какие-нибудь способы?

PS Ваше предложение анализировать тип данных - вполне может быть решением, смущает лишь то, что придется проанализировать несколько совокупностей входных данных и для каждой - своя ветка в конструкторе. Боюсь, что конструктор разрастется до нечитаемости (реальная зачача немного сложнее, чем та, что я здесь привел).
pasaranax
могу предложить вот такой метод с определением типов, как ты и хотел, 3 “конструктора”, все читаемо
class A(object):
def __init__(self, a, b=None):
if type(a).__name__ == 'int':
self._init1(a, b)
elif type(a).__name__ == 'list':
self._init2(a, b)
elif type(a).__name__ == 'str':
self._init3(a)

def _init1(self, n, f):
print "первый конструктор делает свои дела"

def _init2(self, w, f):
print "второй конструктор делает свои дела"

def _init3(self, s):
print "третий конструктор делает свои дела"


a1 = A(123, hex(0))
a2 = A([1, 2, 3], hex(0))
a3 = A("{'f': cos(), 'w': [0,0,1]}")
И на счет передачи функции, тебе надо результат работы функции передать или саму функцию как объект? А то в этои случае передается результат.
Dmitrij
pasaranax
могу предложить вот такой метод с определением типов, как ты и хотел, 3 “конструктора”, все читаемо
Аха, спасибо большое, так действительно гораздо более наглядно
pasaranax
И на счет передачи функции, тебе надо результат работы функции передать или саму функцию как объект? А то в этои случае передается результат.
Точно. Спасибо за подсказку, я бы на этом еще споткнулся.

sky
Реализация перегрузки функций
Ого, похоже, это гораздо более мощная штуковина, и гораздо более сложная :) Во всяком случае, мне еще рано такой пользоваться - я там понял хорошо, если половину… вернусь к ней попозже, когда наберусь опыта побольше
QZip
Можно еще тупо поименовать аргументы
class A(object):
def __init__(self,s=None,n=None,w=None,f=None):
if s!=None:#если передан s
...
elif n!=None:#если n
...
...#и так далее
a1 = A(w=10,f=cos())
a2 = A(n=[1,1,2,0],f=sin())
a3 = A(s="{'f': cos(), 'w': [0,0,1]}")
pasaranax
QZip
Можно еще тупо поименовать аргументы
class A(object):
def __init__(self,s=None,n=None,w=None,f=None):
if s!=None:#если передан s
...
elif n!=None:#если n
...
...#и так далее
a1 = A(w=10,f=cos())
a2 = A(n=[1,1,2,0],f=sin())
a3 = A(s="{'f': cos(), 'w': [0,0,1]}")
странно, у меня с именованными аргументами не получалось, я подумал, что в конструкторе они не канают
QZip
Действительно, странно.
Python 2.6.2, если что.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB