Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Properties for modules?

0 views
Skip to first unread message

Ed Leafe

unread,
Jun 11, 2007, 5:35:00 PM6/11/07
to pytho...@python.org
I have a simple module that reads in values from disk when imported,
and stores them in attributes, allowing for code like:

>>> import moduleFoo
>>> print moduleFoo.someSetting
'the value'

What I'd like to do is have a more property-like behavior, so that
if they try to set the value of moduleFoo.someSetting, it also
persists it to disk. But properties are really only useful in
instances of classes; if I define 'someSetting' as a property at the
module level, I get:

>>> import moduleFoo
>>> print moduleFoo.someSetting
<property object at 0x78a990>

Does anyone know any good tricks for getting property-like behavior
here?

-- Ed Leafe
-- http://leafe.com
-- http://dabodev.com


Steven Bethard

unread,
Jun 11, 2007, 5:55:58 PM6/11/07
to

I typically define a module wrapping class like::

class GiveThisModuleProperties(object):
def __init__(self, module_name):
self._module = sys.modules[module_name]
sys.modules[module_name] = self
# now define whatever behavior you need
def __getattr__(...):
...
def __setattr__(...):
...

Then, in the module you want wrapped, you write::

GiveThisModuleProperties(__name__)

The trick here is basically that we replace the module object in
sys.modules with a class instance that wraps the module with whatever
extra behavior is necessary.

It's not beautiful, but it does seem to work. ;-)

STeVe

Steve Howell

unread,
Jun 11, 2007, 6:05:20 PM6/11/07
to Ed Leafe, pytho...@python.org

--- Ed Leafe <e...@leafe.com> wrote:

> I have a simple module that reads in values from
> disk when imported,
> and stores them in attributes, allowing for code
> like:
>
> >>> import moduleFoo
> >>> print moduleFoo.someSetting
> 'the value'
>
> What I'd like to do is have a more property-like
> behavior, so that
> if they try to set the value of
> moduleFoo.someSetting, it also
> persists it to disk. But properties are really only
> useful in
> instances of classes; if I define 'someSetting' as a
> property at the
> module level, I get:
>
> >>> import moduleFoo
> >>> print moduleFoo.someSetting
> <property object at 0x78a990>
>
> Does anyone know any good tricks for getting
> property-like behavior
> here?
>

Sorry to stray from your question a bit, but you are
reminding me of something that happens a lot in my
coding. I'll code something as a module, then turn it
into a class. I usually do it early enough in the
ballgame that it's not a major undertaking, but it can
still be kind of tedious.

In a lot of ways modules and classes are
interchangable in how you use them, and I'm curious
what strategies other people adopt in making the
progression from modules to classes. For example, is
there some sort of magical way to turn a module into a
class, i.e. to make it less of a singleton? I promise
to horribly abuse such techniques till I learn
better...

Right now, when I make the conversion, I just kind of
mechanically indent a bunch of functions, put a
"class" statement on top of them, add some self-dots,
etc., but it feels kind of wrong at times.



____________________________________________________________________________________
Got a little couch potato?
Check out fun summer activities for kids.
http://search.yahoo.com/search?fr=oni_on_mail&p=summer+activities+for+kids&cs=bz

James Stroud

unread,
Jun 11, 2007, 6:06:29 PM6/11/07
to


Most pythonic and recommended would be to create a class inside
moduleFoo that has the functionality you describe, instantiate an
instance, and then import reference to the instance into the local
namespace. This will be essentially equivalent to "module level
properties" as you describe them.


# moduleFoo.py

def get_setting(self, name):
return do_whatever(name)

def set_setting(self, name, arg):
return do_whatever_else(name, arg)

class Foo(object):
someSetting = property(set_setting, get_setting)

foo = Foo()


# program.py

from moduleFoo import foo

foo.someSetting = some_value

# etc.


Of course, its probably better to move the getters and setters into Foo
if they will only be used in foo context.

James

James Stroud

unread,
Jun 11, 2007, 6:08:23 PM6/11/07
to
James Stroud wrote:
> # moduleFoo.py
>
> def get_setting(self, name):
> return do_whatever(name)
>
> def set_setting(self, name, arg):
> return do_whatever_else(name, arg)
>
> class Foo(object):
> someSetting = property(set_setting, get_setting)
>
> foo = Foo()


someSetting = property(set_setting, get_setting)

should be

someSetting = property(get_setting, set_setting)

James

Ed Leafe

unread,
Jun 11, 2007, 8:40:32 PM6/11/07
to pytho...@python.org
On Jun 11, 2007, at 5:55 PM, Steven Bethard wrote:

> I typically define a module wrapping class like::
>
> class GiveThisModuleProperties(object):
> def __init__(self, module_name):
> self._module = sys.modules[module_name]
> sys.modules[module_name] = self
> # now define whatever behavior you need
> def __getattr__(...):
> ...
> def __setattr__(...):
> ...
>
> Then, in the module you want wrapped, you write::
>
> GiveThisModuleProperties(__name__)
>
> The trick here is basically that we replace the module object in
> sys.modules with a class instance that wraps the module with whatever
> extra behavior is necessary.

OK, I see the trick involved. Yes, that does work for what I need.
Thanks!

0 new messages