Форум сайта python.su
0
Дело в том что я недавно начал изучать Python и у меня возникают вопросы на которые трудно найти ответ в документации. Задача состоит в следующем: отделить реализацию взаимодействия с хранилищем данных от логики. Задача усложняется тем, что различные наборы данных нуждаются в различных методах взаимодействия с БД, а абстрагировать ух как хочется. То есть задача сводится к реализации некоего метода представлявшего из себя что то среднее между потернами строителя и фасада. Но это все преамбула! Вопрос: Стоит ли мне оторвать руки и повесить на шею табличку “Он убивает котят каждой строкой своего кода!” или же все в порядке вещей? Да чуть не забыл, будем считать что все данные валидны.
def insert(self, values = {}, target = ''): inst = locals().get(target)() for parameter in values: inst.__dict__[param] = values[parameter] ...
Офлайн
568
totoerЗадача интересная, если она нужна Вам в целях академических. Если же Вам нужна именно практическая реализация, то советую не изобретать велосипед, а взять уже готовые решения, например http://www.sqlalchemy.org/, лучше все равно вряд ли получится.
Задача состоит в следующем: отделить реализацию взаимодействия с хранилищем данных от логики.
Офлайн
0
Спасибо за интересный вариант. К сожалению использовать slqalchemy не совсем возможно по одной простой причине БД не SQL. Собственно говоря мне было интересно узнать имею ли я право использовать конкретные две строчки кода.
inst = locals().get(target)() inst.__dict__[param] = values[parameter]
Офлайн
568
А какая конкретно задача решается этими строчками, может мы предложим вариант покошернее?
Офлайн
0
Для начало надо сказать что приложение работает в среде google web engine соответственно использует её окружение включая БД. Зада состоит в разделении реализации логики от реализации взаимодействия с БД.
В общем случае код реализации интерфейса работы с БД выглядит так:
consumer.py
from producer import DataBaseInterface class NewEmployee: ... def make(self, name, salary): values['name'] = name values['salary'] = str(salary) DataBaseInterface.insert(values, 'Employee') ... class NewManager: ... def make(self, name, salary, departament): values['name'] = name values['salary'] = str(salary) values['departament'] = departament DataBaseInterface.insert(values, 'Manager')
from google.appengine.ext import db class Employee(db.Model): name = StringProperty() salary = InteregProperty() class Manager(db.Model): name = StringProperty() salary = InteregProperty() departament = StringProperty() class DataBaseInterface: ... def insert(self, values, target): #Допустим тут данные проходят валидность, я к тому что значения values и target на данном этапе можно считать валидными instModel = locals().get(target)() for parameter in values: instModel.__dict__[param] = values[parameter] instModel.put()
Отредактировано totoer (Окт. 24, 2012 16:11:23)
Офлайн
20
1. Для использования `__dict__` нужны очень везкие аргументы, обрати внимание на `setattr`, `getattr` и `vars`.
2. `locals`, серьёзно? Он же не будет тут работать, там будет только self, values и target. Тогда уж `globals` используй. Хотя оба варианта – дурной тон. Укажи явно поддерживаемые типы в каком-нибудь своём списочке. Как он будет пополняться – тысяча вариантов, для красоты можно приспособить декораторы и/или метаклассы, глянь Martian.
3. Если `insert` не будет методом класса или статическим (а судя по self, он не первое и не второе), то попытка его использования из consumer, указанным в примере образом, потерпит неудачу.
4. Наследуйся от `object`.
5. Познай *args и **kwargs.
..bw
Офлайн
0
bwСори за неточности в коде писал не думая, как пример.
1. Для использования `__dict__` нужны очень везкие аргументы, обрати внимание на `setattr`, `getattr` и `vars`.
2. `locals`, серьёзно? Он же не будет тут работать, там будет только self, values и target. Тогда уж `globals` используй. Хотя оба варианта – дурной тон. Укажи явно поддерживаемые типы в каком-нибудь своём списочке. Как он будет пополняться – тысяча вариантов, для красоты можно приспособить декораторы и/или метаклассы, глянь Martian.
3. Если `insert` не будет методом класса или статическим (а судя по self, он не первое и не второе), то попытка его использования из consumer, указанным в примере образом, потерпит неудачу.
4. Наследуйся от `object`.
5. Познай *args и **kwargs.
class Empoyee(db.Model): def __setattr__(self, name, value): super(Empoyee, self).__setattr__(name, value)
Офлайн
20
Может быть пусть класс сам отвечает за то как себя сохранять?
class Person: def __init__(self, id=-1, name="", age=-1): self.id = id self.name = name self.age = age def insert(self): con = DB.getConnection() con.execute("INSERT INTO Persons VALUES(?, ?)", [self.name, self.age]) con.close() def update(self): con = DB.getConnection() con.execute("UPDATE Persons SET name=?, age=? WHERE id=?", [self.name, self.age, self.id]) con.close() @staticmethod def select(query, params): con = DB.getConnection() cur = con.execute(query, params) personData = cur.fetchone() con.close() id = personData[0] name = personData[1] age = personData[2] return Person(id, name, age) @staticmethod def getByName(name): return select("SELECT * FROM Persons WHERE name=?", [name]) @staticmethod def getByAge(age): return select("SELECT * FROM Persons WHERE age=?", [age])
Отредактировано Soteric (Окт. 24, 2012 19:45:13)
Офлайн
173
Получается вы хотите писать:
values['name'] = name values['salary'] = str(salary) values['departament'] = departament DataBaseInterface.insert(values, 'Manager')
manger = Manager(name='Jhon', salary=9000, department='IT') manager.put()
totoerНаверное имелось в виду
В случае с __setattr__ вы предлагаете изменить модели, добавив метод __setattr__
setattr(instModel, param, values[param])
Офлайн
43
какое метапрограммирование зачем же так все усложнять просто вместо
inst.__dict__[name] = value
setattr(inst, name, value)
К сожалению использовать slqalchemy не совсем возможно по одной простой причине БД не SQLМне думается это все таки то что вам нужно, ага.
Отредактировано sergeek (Окт. 24, 2012 20:05:08)
Офлайн