reflection as in Java: how to create an instance from a classname

Discussion in 'Python' started by guss, Jan 5, 2009.

  1. guss

    guss Guest

    I cannot find a satisfying answer to this question on the web so let's
    try here.

    My problem is the following, I would like to instantiate some object
    from a configuration file that would contain class names like for
    example classname=org.common.resource.MyResource.
    Here my resource is the class to instanciate and it is in the module
    resource that is in a package hierachy.

    In fact I would like to do something very similar to the Java:

    klass = Class.forname("org.common.resource.MyResource")

    instance = klass.newInstance()

    The second line is easy once I have a classobj but I have some
    problems to find the right recipe for getting it.

    I know how to create a class from scratch with new.classobj but how do
    you get a class object and then create an object ?

    I would like a recipe working for all cases (whatever the module is
    not the local one ...)

    Maybe I should follow another idiom I don't know ?

    Thanks your help

    Guillaume
    guss, Jan 5, 2009
    #1
    1. Advertising

  2. guss a écrit :
    > I cannot find a satisfying answer to this question on the web so let's
    > try here.
    >
    > My problem is the following, I would like to instantiate some object
    > from a configuration file that would contain class names like for
    > example classname=org.common.resource.MyResource.
    > Here my resource is the class to instanciate and it is in the module
    > resource that is in a package hierachy.
    >
    > In fact I would like to do something very similar to the Java:
    >
    > klass = Class.forname("org.common.resource.MyResource")
    >
    > instance = klass.newInstance()
    >
    > The second line is easy once I have a classobj but I have some
    > problems to find the right recipe for getting it.
    >
    > I know how to create a class from scratch with new.classobj but how do
    > you get a class object and then create an object ?
    >
    > I would like a recipe working for all cases (whatever the module is
    > not the local one ...)


    use __import__ to get the module object, then getattr(module, classname)
    to get the class object (sorry, no much time right now to give you a
    full recipe, but that should be enough to get you started).

    HTH
    Bruno Desthuilliers, Jan 5, 2009
    #2
    1. Advertising

  3. guss

    guss Guest

    hi Thanks for the tip but I had to play with the __import__ func a
    bit.
    Indeed to load not only the top module with __import__ one needs to
    try to load an object from the module:

    Here is my forname:

    def forname(modname, classname):
    module = __import__(modname,globals(),locals(),['NoName'],-1)
    classobj = getattr(module, classname)
    return classobj

    Like that I can load MyError from the module org.myapp.exceptions

    >>> c = forname('org.myapp.exceptions','MyError')
    >>> instance = c('My Message')


    If I do not put 'NoName' that is a fake object only module will be org
    and not org.myapp.exceptions. This is strange ?

    I think Python has all the elements for doing java like reflection and
    introspection and even more but the API is not as mature and it is
    quite difficult to find the information.
    There is the need for a high level API.

    Maybe it already exists, if anyone knows please tell me.
    Thanks.

    Guillaume

    On Jan 5, 5:34 pm, Bruno Desthuilliers <bruno.
    > wrote:
    > guss a écrit :
    >
    >
    >
    > > I cannot find a satisfying answer to this question on the web so let's
    > > try here.

    >
    > > My problem is the following, I would like to instantiate some object
    > > from a configuration file that would contain class names like for
    > > example classname=org.common.resource.MyResource.
    > > Here my resource is the class to instanciate and it is in the module
    > > resource that is in a package hierachy.

    >
    > > In fact I would like to do something very similar to the Java:

    >
    > > klass = Class.forname("org.common.resource.MyResource")

    >
    > > instance = klass.newInstance()

    >
    > > The second line is easy once I have a classobj but I have some
    > > problems to find the right recipe for getting it.

    >
    > > I know how to create a class from scratch with new.classobj but how do
    > > you get a class object and then create an object ?

    >
    > > I would like a recipe working for all cases (whatever the module is
    > > not the local one ...)

    >
    > use __import__ to get the module object, then getattr(module, classname)
    > to get the class object (sorry, no much time right now to give you a
    > full recipe, but that should be enough to get you started).
    >
    > HTH
    guss, Jan 6, 2009
    #3
  4. guss

    Carl Banks Guest

    On Jan 6, 2:24 am, guss <> wrote:
    > hi Thanks for the tip but I had to play with the __import__ func a
    > bit.
    > Indeed to load not only the top module with __import__ one needs to
    > try to load an object from the module:
    >
    > Here is my forname:
    >
    > def forname(modname, classname):
    >     module = __import__(modname,globals(),locals(),['NoName'],-1)
    >     classobj = getattr(module, classname)
    >     return classobj
    >
    > Like that I can load MyError from the module org.myapp.exceptions
    >
    > >>> c = forname('org.myapp.exceptions','MyError')
    > >>> instance = c('My Message')

    >
    > If I do not put 'NoName' that is a fake object only module will be org
    > and not org.myapp.exceptions. This is strange ?


    Yes, it's strange. It's that way for historical and logistical
    reasons. Here's how I'd write the function; no need to specify
    modname and classname separately.


    def forname(name):
    parts = name.split(".")
    obj = __import__(".".join(parts[:-1]))
    for part in parts[1:]:
    obj = getattr(obj,part)
    return obj


    > I think Python has all the elements for doing java like reflection and
    > introspection and even more but the API is not as mature and it is
    > quite difficult to find the information.
    > There is the need for a high level API.
    >
    > Maybe it already exists, if anyone knows please tell me.
    > Thanks.


    I'm going to suggest that the reason high-level reflection APIs are
    used so often in Java is to compensate for Java's lack of run-time
    flexibility. If you don't know what class to use or method to call at
    compile-time, the easiest thing to do is to store the name in a string
    and use the Reflection API to get at it at run-time.

    Python, OTOH, is very dynamic, so there is not much demand for spiffy
    introspection APIs. Functions and classes are ordinary objects, so if
    you don't know what function to call or class to use at compile-time,
    you can just pass the objects around. No strings required.

    So what I'm saying is: the Python developers didn't bother to make an
    high-level, easy-to-use __import__ because there really isn't much
    demand for it.


    Carl Banks
    Carl Banks, Jan 6, 2009
    #4
  5. guss

    guss Guest

    Hi Carl

    thanks for your improved forname method.

    Regarding the high level reflection API, it is true that we don't need
    an API as complex as in Java considering the dynamic aspect of Python
    but you have a forname function I needed one so
    it could be nice to have it (and other services related to reflection
    and introspection) standardized in an api supported by default by
    Python.

    Who doesn't need to load or create a class (a plugin object ...) from
    a configuration file these days.

    Cheers Guillaume

    > On Jan 6, 2:24 am, guss <> wrote:
    >
    >
    >
    > > hi Thanks for the tip but I had to play with the __import__ func a
    > > bit.
    > > Indeed to load not only the top module with __import__ one needs to
    > > try to load an object from the module:

    >
    > > Here is my forname:

    >
    > > def forname(modname, classname):
    > >     module = __import__(modname,globals(),locals(),['NoName'],-1)
    > >     classobj = getattr(module, classname)
    > >     return classobj

    >
    > > Like that I can load MyError from the module org.myapp.exceptions

    >
    > > >>> c = forname('org.myapp.exceptions','MyError')
    > > >>> instance = c('My Message')

    >
    > > If I do not put 'NoName' that is a fake object only module will be org
    > > and not org.myapp.exceptions. This is strange ?

    >
    > Yes, it's strange.  It's that way for historical and logistical
    > reasons.  Here's how I'd write the function; no need to specify
    > modname and classname separately.
    >
    > def forname(name):
    >     parts = name.split(".")
    >     obj = __import__(".".join(parts[:-1]))
    >     for part in parts[1:]:
    >         obj = getattr(obj,part)
    >     return obj
    >
    > > I think Python has all the elements for doing java like reflection and
    > > introspection and even more but the API is not as mature and it is
    > > quite difficult to find the information.
    > > There is the need for a high level API.

    >
    > > Maybe it already exists, if anyone knows please tell me.
    > > Thanks.

    >
    > I'm going to suggest that the reason high-level reflection APIs are
    > used so often in Java is to compensate for Java's lack of run-time
    > flexibility.  If you don't know what class to use or method to call at
    > compile-time, the easiest thing to do is to store the name in a string
    > and use the Reflection API to get at it at run-time.
    >
    > Python, OTOH, is very dynamic, so there is not much demand for spiffy
    > introspection APIs.  Functions and classes are ordinary objects, so if
    > you don't know what function to call or class to use at compile-time,
    > you can just pass the objects around.  No strings required.
    >
    > So what I'm saying is: the Python developers didn't bother to make an
    > high-level, easy-to-use __import__ because there really isn't much
    > demand for it.
    >
    > Carl Banks
    guss, Jan 6, 2009
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kris
    Replies:
    8
    Views:
    1,818
    Chris Smith
    Nov 22, 2004
  2. Oliver S.

    classname::classname a type ?

    Oliver S., Sep 11, 2003, in forum: C++
    Replies:
    1
    Views:
    492
    White Wolf
    Sep 11, 2003
  3. Hongzheng Wang
    Replies:
    32
    Views:
    857
  4. Robert Dodier
    Replies:
    5
    Views:
    833
  5. Ante Perkovic

    CSS: "tagname.classname" or ".classname"

    Ante Perkovic, Dec 22, 2003, in forum: Javascript
    Replies:
    2
    Views:
    96
Loading...

Share This Page