Python OOP Problem

  • Thread starter Миклухо
  • Start date
Ð

Миклухо

Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();

For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();

Saw this link http://stackoverflow.com/questions/452969/does-python-have-an-equivalent-to-java-class-forname,
but it doesn't work for me. May be I do something wrong. I just
started to learn python. Help, please.
PS: Sorry for poor English.
Mikluxo
 
D

Daniel Fetchinson

Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();

For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();

Take a look at locals( ) and globals( ).

The detailed answer depends on whether the class is defined in an
imported module or is defined in the current namespace. From your
example it seems the latter.

Just in case it's the former, you could do this:

import module_with_your_class
astring = 'MyObject'
o = getattr( module_with_your_class, astring )

If the class is defined in the module where you are,

class MyObject: pass
astring = 'MyObject'
o = locals( )[astring]( )

If the class MyObject is not local, for example because you need 'o'
in a function body, you can try globals( ) instead of locals( ).


HTH,
Daniel
 
M

Martin v. Loewis

Миклухо said:
Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();

For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();

Saw this link http://stackoverflow.com/questions/452969/does-python-have-an-equivalent-to-java-class-forname,
but it doesn't work for me. May be I do something wrong. I just
started to learn python. Help, please.

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
"MyOtherObject" : MyOtherObject,
"Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin
 
A

Anthony Tolle

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
               "MyOtherObject" : MyOtherObject,
               "Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin

The class needs to be instantiated, so the one line should be as
follows:

o = name2class[class_name]()

--
 
M

Martin v. Loewis

name2class = { "MyObject" : MyObject,
"MyOtherObject" : MyOtherObject,
"Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()
The class needs to be instantiated, so the one line should be as
follows:

o = name2class[class_name]()

Oops - thanks for pointing that out.

Martin
 
Ð

Миклухо

Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();
For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();

Take a look at locals( ) and globals( ).

The detailed answer depends on whether the class is defined in an
imported module or is defined in the current namespace. From your
example it seems the latter.

Just in case it's the former, you could do this:

import module_with_your_class
astring = 'MyObject'
o = getattr( module_with_your_class, astring )

If the class is defined in the module where you are,

class MyObject: pass
astring = 'MyObject'
o = locals( )[astring]( )

If the class MyObject is not local, for example because you need 'o'
in a function body, you can try globals( ) instead of locals( ).

HTH,
Daniel
Thanks for your reply. It's really helpful.
The hierarchy will be something like this(each file is a class):
- RouterTable( where we take the string from db)
Router.py(the class which instantiates MyObject)
-- MyObject.py

-- MyObject2.py

-- MyObject3.py
Because each class should work independently from other and I cannot
stop my program when adding another Object.
 
Ð

Миклухо

Миклухо said:
Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();
For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();
Saw this linkhttp://stackoverflow.com/questions/452969/does-python-have-an-equival...,
but it doesn't work for me. May be I do something wrong. I just
started to learn python. Help, please.

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
               "MyOtherObject" : MyOtherObject,
               "Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.
I'm not sure, if this is solution, but test passed:

myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();
 
Ð

Миклухо

Миклухо said:
Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();
For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();
Saw this linkhttp://stackoverflow.com/questions/452969/does-python-have-an-equival...,
but it doesn't work for me. May be I do something wrong. I just
started to learn python. Help, please.

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
               "MyOtherObject" : MyOtherObject,
               "Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.
I'm not sure, if this is solution, but test passed:

myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();
 
Ð

Миклухо

Миклухо said:
Hi, all. My problem is:
1) I have a database(postgresql)
2)I'm getting some string from database(string is a classname -
written by me).
3)I need to construct new object from this string.
In java it's done by Class.forName().newInstance();
For instance:
1)I receive the string: "MyObject".
2)o = MyObject();
3)o.myfunction();
Saw this linkhttp://stackoverflow.com/questions/452969/does-python-have-an-equival...,
but it doesn't work for me. May be I do something wrong. I just
started to learn python. Help, please.

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
               "MyOtherObject" : MyOtherObject,
               "Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.
I'm not sure, if this is solution, but test passed:

myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();
 
L

Laszlo Nagy

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.
I think you meant "if you add other classes".
I'm not sure, if this is solution, but test passed:

myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();
The same way you can say: this won't work if you need to change your
'ClassName' class. That would require restart of your service. Then you
can use reload(). However, I do not see the big picture. What is your
program suppose to do?

L
 
Ð

Миклухо

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.

I think you meant "if you add other classes".> I'm not sure, if this is solution, but test passed:
myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();

The same way you can say: this won't work if you need to change your
'ClassName' class. That would require restart of your service. Then you
can use reload(). However, I do not see the big picture. What is your
program suppose to do?

  L

The program works under apache(mod_wsgi) and receives different
messages, depends upon the message it should give an answer. There are
a lot types of messages(something like service) - and if I change a
'ClassName' class(mostly I don't change - just throw away from db note
about it(if time of service ended))- other modules(for instance
ClassName2 ClassName3 etc.) work. And if I will edit the main class
(which loads them) all services may be down. That's why it is
important to make a generalized loader - which loads another class.
 
L

Lie Ryan

In this case (you just started to learn Python), I recommend to take
an explicit approach. Create a dictionary that maps class names to
classes:

name2class = { "MyObject" : MyObject,
"MyOtherObject" : MyOtherObject,
"Etc" : Etc }

Then, when you receive the string class_name, you do

o = name2class[class_name]
o.myfunction()

HTH,
Martin

Thanks for reply, but it doesn't fit to my task. If I will add later
other objects(and it will be very often) - I should stop the service,
but that would be very bad.

you don't need to stop any service; just add into the dictionary:
name2class['NewObject'] = NewObject
I'm not sure, if this is solution, but test passed:

myimportmod = __import__('ClassName', globals(), locals(),
['ClassName'], -1)
mod = getattr(_myimportmod, 'ClassName')
o = mod();
o.myfunction();
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top