Newbie namespace question

Discussion in 'Python' started by bcarlso@gmail.com, Dec 22, 2004.

  1. Guest

    I have a variable that I want to make global across all modules, i.e. I
    want it added to the builtin namespace. Is there a way to do this?
     
    , Dec 22, 2004
    #1
    1. Advertising

  2. deelan Guest

    wrote:
    > I have a variable that I want to make global across all modules, i.e. I
    > want it added to the builtin namespace. Is there a way to do this?

    i would not pollute built-ins namespace.
    how about:

    ### a.py
    FOO = "I'm a global foo!"

    ### b.py
    import a

    print a.FOO


    HTH,
    deelan

    --
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    <#me> a foaf:person ; foaf:nick "deelan" ;
    foaf:weblog <http://blog.deelan.com/> .
     
    deelan, Dec 22, 2004
    #2
    1. Advertising

  3. Steve Holden Guest

    wrote:

    > I have a variable that I want to make global across all modules, i.e. I
    > want it added to the builtin namespace. Is there a way to do this?
    >

    Of course: you can do *anything* in Python. I'm not sure this is to be
    recommended, but since you ask ... if you have

    # mymod.py
    print myname

    then in some other module (and here specifically in the interactive
    interpreter) you can bind a value to "myname" in __builtins__ and it
    will be seen by mymod.py when it's imported:

    >>> __builtins__.myname = "MyValue"
    >>> myname

    'MyValue'
    >>> import mymod

    MyValue
    >>>


    Having said all that, you have to be careful, since it's necessary to
    explicity assign to __builtins__.myname to change the value - if you
    just assign to myname then you create a new myname in the module's
    global namespace that will make the name in __builtins__ inaccessible.

    So, what with that plus the way the names automagically appear it's
    probably something to relegate to the "definitely not best practice"
    category.

    regards
    Steve
    --
    Steve Holden http://www.holdenweb.com/
    Python Web Programming http://pydish.holdenweb.com/
    Holden Web LLC +1 703 861 4237 +1 800 494 3119
     
    Steve Holden, Dec 22, 2004
    #3
  4. Guest

    Here's my situation, I've created some scripts to configure WebSphere
    and the WAS scripting engine assigns the variable AdminConfig to a Java
    object. I have created classes that wrap the AdminConfig settings,
    simplifying the interface for those who want to script their server
    installs.

    At the command line, I pass the main script in and AdminConfig is
    automatically assigned and placed in the global namespace and control
    is passed to the main script.

    Therefore...

    #configure_server_foo.py
    from jdbc import DataSource

    print globals()["AdminConfig"] # Will print com.ibm.yada.yada.yada

    # Create a couple of data sources
    ds = DataSource("ServerName")
    ds.create("dsname1", "connectionInfo", "etc")
    ds.create("dsname2", "connectionInfo", "etc")

    Now, in jdbc.py I have

    #jdbc.py
    class DataSource:
    def __init__(self, servername):
    self.servername = servername

    def create(name, connectionInfo, etc):
    #Call the IBM supplied WebSphere config object
    AdminConfig.create('DataSource')

    Run it and get a name error, which, makes sense.
    If I try to use the standard import solution as deelan suggests I have
    a circular reference on the imports and I get an error that it can't
    import class DataSource (presumbably because it hasn't gotten far
    enough through jdbc.py to realize that there's a DataSource class
    defined.

    Any insight would be greatly appreciated, and thanks to both deelan and
    Steve for your help.
     
    , Dec 22, 2004
    #4
  5. Brandon Guest

    And I just realized that Jython doesn't support the __builtins__
    variable... :(
     
    Brandon, Dec 22, 2004
    #5
  6. Peter Hansen Guest

    Steve Holden wrote:
    > then in some other module (and here specifically in the interactive
    > interpreter) you can bind a value to "myname" in __builtins__ and it
    > will be seen by mymod.py when it's imported:
    >
    > >>> __builtins__.myname = "MyValue"


    Steve's basic premise is correct, but he's chosen the wrong
    name to use. As Fredrik Lundh has written here
    http://mail.python.org/pipermail/python-list/2002-June/109090.html
    the name above is an implementation detail and one should
    always do this instead:

    import __builtin__
    __builtin__.myname = "MyValue"

    And doing so reinforces the idea that this is Almost Always
    a Bad Idea. :)

    -Peter
     
    Peter Hansen, Dec 22, 2004
    #6
  7. Brandon Guest

    Thanks, that worked to get me past the "problem". Did you see my post
    regarding my issue? I just know that there's a "Python way" to resolve
    my issue, so if anyone has a better way, I'm really interested.
    Not only does it feel like a hack, it looks like one too! Even worse!
     
    Brandon, Dec 22, 2004
    #7
  8. deelan Guest

    wrote:
    (...)
    >
    > Run it and get a name error, which, makes sense.
    > If I try to use the standard import solution as deelan suggests I have
    > a circular reference on the imports and I get an error that it can't
    > import class DataSource (presumbably because it hasn't gotten far
    > enough through jdbc.py to realize that there's a DataSource class
    > defined.

    oh, i see. so the scenario is more complex.

    >
    > Any insight would be greatly appreciated, and thanks to both deelan and
    > Steve for your help.


    i believe that to avoid circular refs errors remember you can
    lazy-import, for example here i'm importing the email package:

    >>> m = __import__('email')
    >>> m

    <module 'email' from 'C:\Python\lib\email\__init__.pyc'>

    check help(__import__) for futher details.

    bye.

    --
    @prefix foaf: <http://xmlns.com/foaf/0.1/> .
    <#me> a foaf:person ; foaf:nick "deelan" ;
    foaf:weblog <http://blog.deelan.com/> .
     
    deelan, Dec 22, 2004
    #8
  9. Jeff Shannon Guest

    wrote:

    >Now, in jdbc.py I have
    >
    >#jdbc.py
    >class DataSource:
    >def __init__(self, servername):
    >self.servername = servername
    >
    >def create(name, connectionInfo, etc):
    >#Call the IBM supplied WebSphere config object
    >AdminConfig.create('DataSource')
    >
    >Run it and get a name error, which, makes sense.
    >If I try to use the standard import solution as deelan suggests I have
    >a circular reference on the imports and I get an error that it can't
    >import class DataSource (presumbably because it hasn't gotten far
    >enough through jdbc.py to realize that there's a DataSource class
    >defined.
    >
    >


    How about you try this?

    def create(name, connectionInfo, ...):
    from configure_server_foo import AdminConfig
    AdminConfig.create('DataSource')

    This way, jdbc.py won't try to import configure_server.foo until
    create() is called. By deferring that import, you should be able to
    avoid the circular import problem...

    Jeff Shannon
    Technician/Programmer
    Credit International
     
    Jeff Shannon, Dec 22, 2004
    #9
  10. Peter Hansen Guest

    deelan wrote:
    > i believe that to avoid circular refs errors remember you can
    > lazy-import, for example here i'm importing the email package:
    >
    >>>> m = __import__('email')
    >>>> m

    >
    > <module 'email' from 'C:\Python\lib\email\__init__.pyc'>
    >
    > check help(__import__) for futher details.


    I'm not sure what you think that does, but I don't
    think it does it.

    The code you show above is no more "lazy" than a simple
    "import email as m" would have been, I believe.

    All statements are executed as they are encountered
    during import, so any that are no inside a function
    or class definition, or protected by a conditional
    control structure in some way, will be executed right
    away, rather than lazily.

    I may have misinterpreted what you were trying to say...

    -Peter
     
    Peter Hansen, Dec 22, 2004
    #10
  11. Peter Hansen Guest

    Brandon wrote:
    > Thanks, that worked to get me past the "problem". Did you see my post
    > regarding my issue? I just know that there's a "Python way" to resolve
    > my issue, so if anyone has a better way, I'm really interested.
    > Not only does it feel like a hack, it looks like one too! Even worse!


    If you mean the one you describe in your post with the Jython
    code, I can't help, mainly because I can't parse it. For
    one thing I think you are using TABs instead of spaces, and
    many newsreaders will eliminate leading tabs so it makes the
    code pretty hard to decipher. I could probably figure it out
    anyway, except that I think you have a bug as well:

    #jdbc.py
    class DataSource:
    def __init__(self, servername):
    self.servername = servername

    def create(name, connectionInfo, etc):
    #Call the IBM supplied WebSphere config object
    AdminConfig.create('DataSource')


    This is how it looked to me. The presumed bug is in the "create"
    method definition, where you are not supplying a "self" parameter.
    At least, I assume that is a method of DataSource and not
    a module-level function, because in the previous code you were
    trying to call ds.create() where ds was a DataSource object.

    I'd probably have some ideas if you reposted with leading
    spaces and explained or fixed the supposed bug.

    -Peter
     
    Peter Hansen, Dec 22, 2004
    #11
  12. Brandon Guest

    Peter,

    You're correct about the bug. I did need a 'self' parm... I was just
    winging the example because the actual code is pretty large. I'm using
    google groups for my posting and it didn't carry spaces through (I did
    use spaces and not tabs).

    The "fix" or workaround was to import __builtin__ and add the
    AdminConfig reference there in configure_server_foo.py as follows:

    import __builtin__
    __builtin__.AdminConfig = AdminConfig

    As for the indentations, substitute ~ with a space.

    Hopefully, a bug free and "indented" version. :)

    #jdbc.py
    class DataSource:
    ~~~def __init__(self, servername):
    ~~~~~~self.servername = servername

    ~~~def create(self, name, connectionInfo, etc):
    ~~~~~~#Call the IBM supplied WebSphere config object
    ~~~~~~AdminConfig.create('DataSource')
     
    Brandon, Dec 22, 2004
    #12
  13. Nick Coghlan Guest

    Brandon wrote:
    > Peter,
    >
    > You're correct about the bug. I did need a 'self' parm... I was just
    > winging the example because the actual code is pretty large. I'm using
    > google groups for my posting and it didn't carry spaces through (I did
    > use spaces and not tabs).
    >
    > The "fix" or workaround was to import __builtin__ and add the
    > AdminConfig reference there in configure_server_foo.py as follows:
    >
    > import __builtin__
    > __builtin__.AdminConfig = AdminConfig
    >
    > As for the indentations, substitute ~ with a space.
    >
    > Hopefully, a bug free and "indented" version. :)
    >
    > #jdbc.py
    > class DataSource:
    > ~~~def __init__(self, servername):
    > ~~~~~~self.servername = servername
    >
    > ~~~def create(self, name, connectionInfo, etc):
    > ~~~~~~#Call the IBM supplied WebSphere config object
    > ~~~~~~AdminConfig.create('DataSource')
    >


    Is there any particular reason DataSource can't be modified to accept a
    reference to the AdminConfig as a constructor argument? Or as a class attribute?

    Alternatively, here's another trick to 'nicely' set a module global from outside
    a module:

    #jdbc.py
    def setAdminConfig(adm_cfg):
    global AdminConfig
    AdminConfig = adm_cfg

    However, if you would prefer not to alter jdbc.py, consider trying:

    import jdbc
    jdbc.AdminConfig = AdminConfig


    Global variables are bad karma to start with, and monkeying with __builtin__ is
    even worse :)

    Cheers,
    Nick.

    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Dec 23, 2004
    #13
  14. Brandon Guest

    I did the constructor thing and just didn't like it, it didn't feel
    clean (I know, I know and monkeying with __builtin__ is?)

    As for global, that will just make it modlue-level global (I think?)
    and I have this reference in multiple modules. I think I tried it
    already, but I can't remember for sure... Anyway, all of this got me
    brainstorming and I think I've got a solution that I think is clean and
    will be effective, I'll bust it out and post it here for comments.
    Thanks for your input!
     
    Brandon, Dec 23, 2004
    #14
  15. Nick Coghlan Guest

    Brandon wrote:
    > I did the constructor thing and just didn't like it, it didn't feel
    > clean (I know, I know and monkeying with __builtin__ is?)
    >
    > As for global, that will just make it modlue-level global (I think?)
    > and I have this reference in multiple modules. I think I tried it
    > already, but I can't remember for sure... Anyway, all of this got me
    > brainstorming and I think I've got a solution that I think is clean and
    > will be effective, I'll bust it out and post it here for comments.
    > Thanks for your input!
    >

    Another option for you to consider:

    #__main__ ( I forget the script's name)
    import app_config
    app_config.setConfiguration(AdminConfig)

    from jdbc import DataStore
    . . .etc


    #jdbc.py
    from app_config import AdminConfig
    .. . .etc


    #app_config.py
    def setConfiguration(adm_cfg):
    global AdminConfig
    AdminConfig = adm_cfg


    The reason the import solution was breaking for you earlier was that you were
    setting up circular imports by using your main script as the holder for the
    global configuration.

    By creating a special 'configuration data' module, you can use that to store the
    data, and every module that needs it can import it without worrying about
    circular imports.

    Any extra global configuration properties can be added by updating the
    'setConfiguration' function.

    Cheers,
    Nick.

    --
    Nick Coghlan | | Brisbane, Australia
    ---------------------------------------------------------------
    http://boredomandlaziness.skystorm.net
     
    Nick Coghlan, Dec 23, 2004
    #15
  16. Peter Hansen <> wrote:

    > I'm not sure what you think that does, but I don't
    > think it does it.


    QOTW +1 !!!


    Alex
     
    Alex Martelli, Dec 24, 2004
    #16
    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. Èý¹â
    Replies:
    1
    Views:
    585
    William F. Robertson, Jr.
    Jul 29, 2003
  2. Replies:
    0
    Views:
    5,146
  3. Anonymous
    Replies:
    3
    Views:
    542
    Ron Natalie
    Aug 18, 2003
  4. Jason Heyes
    Replies:
    1
    Views:
    456
    Woebegone
    Nov 19, 2004
  5. Petter Reinholdtsen
    Replies:
    9
    Views:
    4,397
    Howard
    Nov 29, 2004
Loading...

Share This Page