Форум сайта python.su
Здравствуйте, господа Питонисты!
У меня должна программа делать следующее
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)
Офлайн
Сколько у вас модулей с такими классами? Если немного, то не мучайтесь и проимпортируйте все.
Если много, то да, нужно использовать __import__.
Покажите образчик кода, который не работает, потому как теоретически трудно осознать что там у вас не работает.
Офлайн
mikluxo
По данной вами ссылке все более или менее прилично описано. Пока не покажете ваш проблемный код - больше советовать не имеет смысла.
Офлайн
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
myimportmod = __import__('ClassName', globals(), locals(), ['ClassName'], -1)
mod = getattr(myimportmod, 'ClassName')
o = mod();
o.myfunction();
Отредактировано (Дек. 29, 2009 06:05:07)
Офлайн
mikluxo, а вы рассматривали варинат помещения этих ваших модулей - обработчиков акций в БД со своим импортером?
Кажется, задача диктует именно этот подход.
Т.е. чтобы вызов выглядел так:
from user_actions.specific_actions_name import myfunction #или что там у вас, класс?
myfunction()
Если нужно помочь - мое мыло andrew<dot>svetlov<at>gmail<dot>com
Тем более что стоило бы глянуть на ваши существующие use cases и быстро задать ряд доп вопросов.
Отредактировано (Дек. 29, 2009 08:20:41)
Офлайн
mikluxoВот вам примерчик работающий. Смысл в том, что __import__-ом импортируется класс верхнего уровня, а дальше все делается gettattr-ом:
D = get_class(“MyClass.MyClass”) - не канает.
MyClass - Лежит в файле MyClass.py в том же каталоге, что и главный модуль(под модулем подразумевается один класс в одном файле).
package = __import__("my_package.MyClass")
module = getattr(package, "MyClass")
my_class = getattr(module, "MyClass")
instance = my_class()
Офлайн
Андрей СветловНе совсем понял схему. Т.е. спрятать все в пакет, или что Вы имеете в виду?
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”
Офлайн
mikluxoНу, вообще-то это стандартная метода дистрибуции и не только для Python. А site-packages - специальное место для 3rd party пакетов.
Теперь точно создам пакет. Только в питоновскую директорию не хочется(вдруг кто-нибудь после меня возьмет поменяет системный модуль и приедем тогда). Поэтому в текущей директории вложенную папку для модулей сделаю.
Офлайн