Static properties

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Per Erik Stendahl

    Static properties

    Hello everyone,

    Is it possible to define "static properties" in a class?

    Example:
    I have a class, Path, that wraps a lot of os.* and os.path.* functions
    (and others), so I can write things like this:

    x = Path('/usr/local/some/file')
    if x.IsFile:
    contents = x.Read()
    ...

    Now, I would like to wrap os.getcwd(). I can do it like this:

    class Path:
    def CurrentDirector y():
    return os.getcwd()
    CurrentDirector y = staticmethod(Cu rrentDirectory)

    pwd = Path.CurrentDir ectory()

    Question: Can I make CurrentDirector y a property? Just adding
    CurrentDirector y = property(Curren tDirectory) after the staticmethod
    line didn't work, unsurprisingly. :-)

    Regards,
    Per Erik Stendahl
  • Alex Martelli

    #2
    Re: Static properties

    Per Erik Stendahl <python-spam@berrs.net> wrote:
    [color=blue]
    > Hello everyone,
    >
    > Is it possible to define "static properties" in a class?[/color]

    Yes, but only by defining a custom metaclass to be the type of that
    class. Properties are defined in the type, not in the instance; so, for
    a class itself to have properties, the class's type, commonly known as
    its metaclass, must be the one defining them.

    [color=blue][color=green][color=darkred]
    >>> class metaPath(type):[/color][/color][/color]
    .... def curdir(cls): return os.getcwd()
    .... curdir = property(curdir )
    ....[color=blue][color=green][color=darkred]
    >>> class Path: __metaclass__ = metaPath[/color][/color][/color]
    ....[color=blue][color=green][color=darkred]
    >>> print Path.curdir[/color][/color][/color]
    /Users/alex/cb/dblite/dblite_0.5


    _However_...:
    [color=blue][color=green][color=darkred]
    >>> print Path().curdir[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: 'Path' object has no attribute 'curdir'[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    if you want to be able to get at property curdir on INSTANCES of Path as
    you normally would for a staticmethod, yet with property syntax, I think
    you need to get a bit more clever than this... descriptors don't get
    looked up two metalevels up, only one...


    Alex

    Comment

    • Bengt Richter

      #3
      Re: Static properties

      On Thu, 26 Aug 2004 23:01:49 +0200, aleaxit@yahoo.c om (Alex Martelli) wrote:
      [color=blue]
      >Per Erik Stendahl <python-spam@berrs.net> wrote:
      >[color=green]
      >> Hello everyone,
      >>
      >> Is it possible to define "static properties" in a class?[/color]
      >
      >Yes, but only by defining a custom metaclass to be the type of that
      >class. Properties are defined in the type, not in the instance; so, for
      >a class itself to have properties, the class's type, commonly known as
      >its metaclass, must be the one defining them.[/color]

      Um, UIAM a property is just a peculiar descriptor, which you can define
      without resorting to metaclass magic. See below ...[color=blue]
      >
      >[color=green][color=darkred]
      >>>> class metaPath(type):[/color][/color]
      >... def curdir(cls): return os.getcwd()
      >... curdir = property(curdir )
      >...[color=green][color=darkred]
      >>>> class Path: __metaclass__ = metaPath[/color][/color]
      >...[color=green][color=darkred]
      >>>> print Path.curdir[/color][/color]
      >/Users/alex/cb/dblite/dblite_0.5
      >
      >
      >_However_... :
      >[color=green][color=darkred]
      >>>> print Path().curdir[/color][/color]
      >Traceback (most recent call last):
      > File "<stdin>", line 1, in ?
      >AttributeError : 'Path' object has no attribute 'curdir'[color=green][color=darkred]
      >>>>[/color][/color]
      >
      >if you want to be able to get at property curdir on INSTANCES of Path as
      >you normally would for a staticmethod, yet with property syntax, I think
      >you need to get a bit more clever than this... descriptors don't get
      >looked up two metalevels up, only one...
      >[/color]
      But you only need one:
      [color=blue][color=green][color=darkred]
      >>> class Path(object):[/color][/color][/color]
      ... class curdir(object):
      ... def __get__(self, inst, cls): return os.getcwd()
      ... curdir = curdir()
      ...[color=blue][color=green][color=darkred]
      >>> import os
      >>> Path.curdir[/color][/color][/color]
      'C:\\pywk\\clp'[color=blue][color=green][color=darkred]
      >>> Path().curdir[/color][/color][/color]
      'C:\\pywk\\clp'

      I wonder if I'll beat you to this post ;-)

      Regards,
      Bengt Richter

      Comment

      • Alex Martelli

        #4
        Re: Static properties

        Bengt Richter <bokr@oz.net> wrote:
        ...[color=blue][color=green][color=darkred]
        > >> Is it possible to define "static properties" in a class?[/color]
        > >
        > >Yes, but only by defining a custom metaclass to be the type of that
        > >class. Properties are defined in the type, not in the instance; so, for
        > >a class itself to have properties, the class's type, commonly known as
        > >its metaclass, must be the one defining them.[/color]
        >
        > Um, UIAM a property is just a peculiar descriptor, which you can define
        > without resorting to metaclass magic. See below ...[/color]

        Hmmm -- I think we're talking somewhat at cross-purposes between
        property, the built-in type, and the effect it has (that accessing an
        attribute runs some code). I was focusing on the formed, but you're
        quite right regarding the latter.
        [color=blue][color=green]
        > >if you want to be able to get at property curdir on INSTANCES of Path as
        > >you normally would for a staticmethod, yet with property syntax, I think
        > >you need to get a bit more clever than this... descriptors don't get
        > >looked up two metalevels up, only one...
        > >[/color]
        > But you only need one:[/color]

        If you don't use property, but "get a bit more clever" by defining a
        custom descriptor as you have, yes:
        [color=blue]
        >[color=green][color=darkred]
        > >>> class Path(object):[/color][/color]
        > ... class curdir(object):
        > ... def __get__(self, inst, cls): return os.getcwd()
        > ... curdir = curdir()[/color]

        Nice. Unfortunately it doesn't extend to data properties, those with a
        __set__ method:
        [color=blue][color=green][color=darkred]
        >>> class Path(object):[/color][/color][/color]
        .... class foo(object):
        .... def __get__(*a): return 'gotten'
        .... def __set__(*a): print 'setten'
        .... foo = foo()
        ....[color=blue][color=green][color=darkred]
        >>> p=Path()
        >>> p.foo[/color][/color][/color]
        'gotten'[color=blue][color=green][color=darkred]
        >>> p.foo=23[/color][/color][/color]
        setten[color=blue][color=green][color=darkred]
        >>> p.foo[/color][/color][/color]
        'gotten'[color=blue][color=green][color=darkred]
        >>> Path.foo[/color][/color][/color]
        'gotten'[color=blue][color=green][color=darkred]
        >>> Path.foo = 23
        >>> Path.foo[/color][/color][/color]
        23[color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        I think (I hope I'm wrong) that to catch 'Path.foo = something' you do
        have to use a custom metaclass (not 'metaclass magic', nothing in the
        least magical about it). But if you're simply willing to trust users to
        just never assign to Path.foo -- you don't need for such assignments to
        cause an error nor for them to cause any specific action -- a simple
        custom descriptor may indeed suffice.


        Alex

        Comment

        • Michael Hudson

          #5
          Re: Static properties

          aleaxit@yahoo.c om (Alex Martelli) writes:
          [color=blue]
          > I think (I hope I'm wrong) that to catch 'Path.foo = something' you
          > do have to use a custom metaclass[/color]

          You're right.

          Cheers,
          mwh

          --
          /* I'd just like to take this moment to point out that C has all
          the expressive power of two dixie cups and a string.
          */ -- Jamie Zawinski from the xkeycaps source

          Comment

          Working...