Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 28, 2009 14:11:18

mikluxo
От:
Зарегистрирован: 2009-12-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Конструирование объекта по имени из строки

Здравствуйте, господа Питонисты!
У меня должна программа делать следующее
1)Забирать строку из БД(postgresql) (реализовал)
2)Конструировать из строки объект(класс - пишу сам) - наподобие Class.forName().newInstance() в Java.
3)Выполнить определенную функцию. (это ерунда)

Пример:
1) получил строку Vasya.
2) создал объект Vasya.
Проблема в том - что я узнаю какой объект конструировать во время выполнения. И как при этом прописывать импорты.

Переезжаю с ПХП. Более менее написано здесь http://stackoverflow.com/questions/452969/does-python-have-an-equivalent-to-java-class-forname, только не понятно, поэтому не получилось адаптировать под свои классы.
Прошу прощения, если ошибся разделом. Если можно тыкните носом, куда копать.
С уважением, mikluxo.



Отредактировано (Дек. 28, 2009 14:12:17)

Офлайн

#2 Дек. 28, 2009 16:33:26

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

Конструирование объекта по имени из строки

Сколько у вас модулей с такими классами? Если немного, то не мучайтесь и проимпортируйте все.
Если много, то да, нужно использовать __import__.
Покажите образчик кода, который не работает, потому как теоретически трудно осознать что там у вас не работает.



Офлайн

#3 Дек. 28, 2009 19:21:35

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Конструирование объекта по имени из строки

mikluxo
По данной вами ссылке все более или менее прилично описано. Пока не покажете ваш проблемный код - больше советовать не имеет смысла.



Офлайн

#4 Дек. 29, 2009 06:03:07

mikluxo
От:
Зарегистрирован: 2009-12-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Конструирование объекта по имени из строки

Ed
Сколько у вас модулей с такими классами? Если немного, то не мучайтесь и проимпортируйте все.
Очень много. Дело в том, что контора занимается обработкой смс сообщений, и каждая акция - отдельный обработчик. Каждый день заводится новая акция, причем остальные постоянно работают - т.е. доимпорты - очень плохое решение. Предложение завести массив name2Mod тоже не есть хорошо. Все более менее работает с пхп(curl), только есть некоторые глюки с юникодом, и куча ненужного кода. В следствии чего решили переписать все на Объекты - выбор пал на Питон.
Собственно код взят из ссылки выше:
def get_class( kls ):
parts = kls.split('.')
module = ".".join(parts[:-1])
m = __import__( module )
for comp in parts[1:]:
m = getattr(m, comp)
return m
D = get_class(“datetime.datetime”) - работает на ура, а вот
D = get_class(“MyClass.MyClass”) - не канает.
MyClass - Лежит в файле MyClass.py в том же каталоге, что и главный модуль(под модулем подразумевается один класс в одном файле).



Вроде бы нашел - буду тестить:
myimportmod = __import__('ClassName', globals(), locals(), ['ClassName'], -1)
mod = getattr(myimportmod, 'ClassName')
o = mod();
o.myfunction();



Отредактировано (Дек. 29, 2009 06:05:07)

Офлайн

#5 Дек. 29, 2009 08:17:11

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Конструирование объекта по имени из строки

mikluxo, а вы рассматривали варинат помещения этих ваших модулей - обработчиков акций в БД со своим импортером?
Кажется, задача диктует именно этот подход.
Т.е. чтобы вызов выглядел так:
from user_actions.specific_actions_name import myfunction #или что там у вас, класс?
myfunction()

Если нужно помочь - мое мыло andrew<dot>svetlov<at>gmail<dot>com
Тем более что стоило бы глянуть на ваши существующие use cases и быстро задать ряд доп вопросов.



Отредактировано (Дек. 29, 2009 08:20:41)

Офлайн

#6 Дек. 29, 2009 11:08:10

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

Конструирование объекта по имени из строки

mikluxo
D = get_class(“MyClass.MyClass”) - не канает.
MyClass - Лежит в файле MyClass.py в том же каталоге, что и главный модуль(под модулем подразумевается один класс в одном файле).
Вот вам примерчик работающий. Смысл в том, что __import__-ом импортируется класс верхнего уровня, а дальше все делается gettattr-ом:
вот как оно лежит на файловой системе:
$ ls -la /usr/lib/python2.5/site-packages/my_package/
total 16
drwxr-xr-x 2 root root 4096 Dec 29 10:48 .
drwxr-xr-x 94 root root 8192 Dec 29 10:50 ..
-rw-r–r– 1 root root 55 Dec 29 10:48 MyClass.py
-rw-r–r– 1 root root 0 Dec 29 10:47 __init__.py
Внутри MyClass.py имеем вот это:
$ cat /usr/lib/python2.5/site-packages/my_package/MyClass.py
class MyClass:
def __init__(self):
print “MyClass”

А так импортируем и используем:
package = __import__("my_package.MyClass")
module = getattr(package, "MyClass")
my_class = getattr(module, "MyClass")
instance = my_class()
Последняя строчка выведет строку “MyClass”



Офлайн

#7 Дек. 30, 2009 12:08:21

mikluxo
От:
Зарегистрирован: 2009-12-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

Конструирование объекта по имени из строки

Андрей Светлов
mikluxo, а вы рассматривали вариант помещения этих ваших модулей - обработчиков акций в БД со своим импортером?
Не совсем понял схему. Т.е. спрятать все в пакет, или что Вы имеете в виду?

Ed
Вот вам примерчик работающий. Смысл в том, что __import__-ом импортируется класс верхнего уровня, а дальше все делается gettattr-ом:
вот как оно лежит на файловой системе:
$ ls -la /usr/lib/python2.5/site-packages/my_package/
total 16
drwxr-xr-x 2 root root 4096 Dec 29 10:48 .
drwxr-xr-x 94 root root 8192 Dec 29 10:50 ..
-rw-r–r– 1 root root 55 Dec 29 10:48 MyClass.py
-rw-r–r– 1 root root 0 Dec 29 10:47 __init__.py
Внутри MyClass.py имеем вот это:
$ cat /usr/lib/python2.5/site-packages/my_package/MyClass.py
class MyClass:
def __init__(self):
print “MyClass”
Спасибо за детальное объяснение. Я как раз думал - как перетащить ее в свой пакет. Теперь точно создам пакет. Только в питоновскую директорию не хочется(вдруг кто-нибудь после меня возьмет поменяет системный модуль и приедем тогда). Поэтому в текущей директории вложенную папку для модулей сделаю.



Офлайн

#8 Дек. 30, 2009 14:02:35

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

Конструирование объекта по имени из строки

mikluxo
Теперь точно создам пакет. Только в питоновскую директорию не хочется(вдруг кто-нибудь после меня возьмет поменяет системный модуль и приедем тогда). Поэтому в текущей директории вложенную папку для модулей сделаю.
Ну, вообще-то это стандартная метода дистрибуции и не только для Python. А site-packages - специальное место для 3rd party пакетов.
В текущей директории что-то создавать имеет смысл для себя, типа потестить там по-быстрому. Да и то для этого лучше использовать virtualenv и подобные тулзы.
Если у вас это должно быть в продакшен рано или поздно, то ‘текущая директория’ - не самое удачное место.
Советую почитать что-нибудь на эту тему. Вдумчиво. Ну вот хоть вот это: http://docs.python.org/install/ для начала.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version