Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 17, 2009 21:07:34

Dmitrij
От:
Зарегистрирован: 2008-03-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

Прошу совета, как лучше сделать:

требуется создать объект, состоящий из нескольких полей:
а) 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]}")
Вопрос: есть ли какая-нибудь возможность объединить эти три вызова в один конструктор? Или же так вообще не делают, и я излишне мудрствую?



Офлайн

#2 Авг. 17, 2009 21:16:16

igor.kaist
От:
Зарегистрирован: 2007-11-12
Сообщения: 1879
Репутация: +  3  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

А если просто типы проверять, и действовать уже согласно ситуации? Или я чего то недопонял…
P.S. вот, пару способов проверить тип переменной, если затруднения в этом…



Отредактировано (Авг. 17, 2009 21:22:28)

Офлайн

#3 Авг. 17, 2009 22:42:26

Dmitrij
От:
Зарегистрирован: 2008-03-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

Спасибо за совет и ссылку. Но, собственно, исходный вопрос у меня был немного шире (каюсь, нечетко его сформулировал).

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

PS Ваше предложение анализировать тип данных - вполне может быть решением, смущает лишь то, что придется проанализировать несколько совокупностей входных данных и для каждой - своя ветка в конструкторе. Боюсь, что конструктор разрастется до нечитаемости (реальная зачача немного сложнее, чем та, что я здесь привел).



Офлайн

#4 Авг. 17, 2009 23:38:27

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

могу предложить вот такой метод с определением типов, как ты и хотел, 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]}")
И на счет передачи функции, тебе надо результат работы функции передать или саму функцию как объект? А то в этои случае передается результат.



Отредактировано (Авг. 17, 2009 23:41:28)

Офлайн

#5 Авг. 18, 2009 01:00:06

sky
От:
Зарегистрирован: 2008-05-26
Сообщения: 24
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

Офлайн

#6 Авг. 18, 2009 09:42:21

Dmitrij
От:
Зарегистрирован: 2008-03-06
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

pasaranax
могу предложить вот такой метод с определением типов, как ты и хотел, 3 “конструктора”, все читаемо
Аха, спасибо большое, так действительно гораздо более наглядно
pasaranax
И на счет передачи функции, тебе надо результат работы функции передать или саму функцию как объект? А то в этои случае передается результат.
Точно. Спасибо за подсказку, я бы на этом еще споткнулся.

sky
Реализация перегрузки функций
Ого, похоже, это гораздо более мощная штуковина, и гораздо более сложная :) Во всяком случае, мне еще рано такой пользоваться - я там понял хорошо, если половину… вернусь к ней попозже, когда наберусь опыта побольше



Офлайн

#7 Авг. 20, 2009 11:37:50

QZip
От:
Зарегистрирован: 2007-11-09
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

Можно еще тупо поименовать аргументы

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]}")



Отредактировано (Авг. 20, 2009 11:38:44)

Офлайн

#8 Авг. 20, 2009 16:52:35

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

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]}")
странно, у меня с именованными аргументами не получалось, я подумал, что в конструкторе они не канают



Офлайн

#9 Авг. 20, 2009 17:12:29

QZip
От:
Зарегистрирован: 2007-11-09
Сообщения: 27
Репутация: +  0  -
Профиль   Отправить e-mail  

Множественные конструкторы (?)

Действительно, странно.
Python 2.6.2, если что.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version