Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 29, 2011 20:45:11

mcnet
От:
Зарегистрирован: 2011-06-29
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Объектные особенности python 2.7

В ходе разработки возникли архитектурные проблемы. Прошу помощи в их решении.

Имеется два метода: mine() и gather(). Оба метода нужны для получения данных,
разница в том, что у методов разные методы connect и разный способ обработки данных.

Для программиста оба метода одинаковы по своему назначению - получение данных, по
этому я хочу их реализовать в одном модуле data, чтобы можно было использовать
следующим образом:

print data().mine()
print data().gather()

Для этого решил использовать разные классы:

class mine:
def mine(self):
return 'mine'
class gather:
def mine(self):
return 'gather'
class data(mine,gather):
pass
Здесь всё работает:
print data().mine()
print data().gather()
Теперь мне нужно управлять соединением с источником данных. Задача: иметь только
одно подключение к серверу с данными.

class mine:
def __init__(self):
print 'mine init'
def mine(self):
return 'I am "mine"'
def __del__(self):
return 'mine destroyed'

class gather:
def __init__(self):
print 'gather init'
def gather(self):
return 'gather'
def __del__(self):
return 'gather destroyed'

class data(mine,gather):
pass
При тестировании, я вижу, что объект gather никак не реагирует на __init__ и __del__:
print data().mine()
print data().gather()
Output:
mine init
I am "mine"
mine init
gather << init не того модуля, что я ожидаю, а del вообще не сработал
С помощью методов __init__ я планирую создавать соединение и хранить его id
в общем статическом свойстве для этих классов.

Подскажите, как подобная задача лучше всего реализуется.
Спасибо.



Офлайн

#2 Июнь 29, 2011 23:12:01

pill
От:
Зарегистрирован: 2010-08-27
Сообщения: 223
Репутация: +  0  -
Профиль   Отправить e-mail  

Объектные особенности python 2.7

>>> data.__mro__
5: (<class '__main__.data'>,
<class '__main__.mine'>,
<class '__main__.gather'>,
<type 'object'>)
(class.__mro__ возвращает порядок наследования)
То есть когда вызывается конструктор класса он ищется сначала в data, потом в mine, затем в gather
(для старых класов - снизу-вверх, слева-направо…)
http://docs.python.org/tutorial/classes.html#multiple-inheritance
Найдя метод __init__ в класе mine интерпретатор его вызывает и на этом поиск заканчивается. Естественно одноименные методы в класcе gather никогда не будут вызваны.

Не понимаю до конца что вы хотите реализовать - попробуйте конкретнее очертить проблему (или подождите кого-то поумнее меня :))

ЗЫ: Завтра прочитаю еще раз, сегодня голова уже не варит…



Отредактировано (Июнь 29, 2011 23:12:33)

Офлайн

#3 Июнь 30, 2011 16:06:36

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Объектные особенности python 2.7

Я бы сделал отдельную сущность Connection и оформил ее как Singleton и не заморачивался бы с множественным наследованием.

Если у вас есть архитектурная проблема и вы решили использовать множественное наследование, то у вас теперь 2 архитектурные проблемы :)

Вот как-то так, например:

#!/usr/bin/python

import time

def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance

@singleton
class Connection():
def __init__(self):
print 'connection init'

class Mine:
def __init__(self):
print 'mine init'
self.connection = Connection()
def mine(self):
return 'I am "mine" %s' % str(self.connection)

class Gather:
def __init__(self):
print 'gather init'
self.connection = Connection()
def gather(self):
return 'I am "gather" %s' % str(self.connection)
def __del__(self):
return 'gather destroyed'

class Data():
def __init__(self):
self._gather = None
self._mine = None

def gather(self):
self._gather = self._gather or Gather()
return self._gather.gather()

def mine(self):
self._mine = self._mine or Mine()
return self._mine.mine()

def gather_first():
print '==== Calling gather() first, then mine()'
data = Data()
print data.gather()
print data.mine()

def mine_first():
print '==== Calling mine() first, then gather()'
data = Data()
print data.mine()
print data.gather()


if __name__ == '__main__':
gather_first()
mine_first()
Можно, кстати, обойтись и без Data, просто реализовав фабрику get_data(), которая вернет либо Gather(), либо Mine() в зависимости от неких условий. Но это зависит от того, какие там у вас условия.

А зачем вам __del__?



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version