Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #2307 > unrolled thread

Alias for an attribute defined in a superclass

Started byBen Finney <ben+python@benfinney.id.au>
First post2011-04-01 09:14 +1100
Last post2011-04-01 11:54 +0200
Articles 7 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Alias for an attribute defined in a superclass Ben Finney <ben+python@benfinney.id.au> - 2011-04-01 09:14 +1100
    Re: Alias for an attribute defined in a superclass Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-04-01 00:14 +0000
      Re: Alias for an attribute defined in a superclass Ben Finney <ben+python@benfinney.id.au> - 2011-04-01 11:59 +1100
    Re: Alias for an attribute defined in a superclass Calvin Spealman <ironfroggy@gmail.com> - 2011-03-31 20:36 -0400
      Re: Alias for an attribute defined in a superclass Ben Finney <ben+python@benfinney.id.au> - 2011-04-01 11:57 +1100
    Re: Alias for an attribute defined in a superclass Raymond Hettinger <python@rcn.com> - 2011-03-31 19:24 -0700
      Re: Alias for an attribute defined in a superclass Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-04-01 11:54 +0200

#2307 — Alias for an attribute defined in a superclass

FromBen Finney <ben+python@benfinney.id.au>
Date2011-04-01 09:14 +1100
SubjectAlias for an attribute defined in a superclass
Message-ID<87sju3ndjo.fsf@benfinney.id.au>
Howdy all,

I want to inherit from a class, and define aliases for many of its
attributes. How can I refer to “the attribute that will be available by
name ‘spam’ once this class is defined”?

    class Foo(object):
        def spam(self):
            pass

        def eggs(self):
            pass

    class Bar(Foo):
        beans = Foo.spam
        mash = Foo.eggs

Is that the right way to do it? Will that leave me open to “unbound
method” or “is not an instance of ‘Bar’” or other problems when using
‘Bar.beans’?

-- 
 \           “If [a technology company] has confidence in their future |
  `\      ability to innovate, the importance they place on protecting |
_o__)     their past innovations really should decline.” —Gary Barnett |
Ben Finney

[toc] | [next] | [standalone]


#2319

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-04-01 00:14 +0000
Message-ID<4d9518f1$0$29992$c3e8da3$5496439d@news.astraweb.com>
In reply to#2307
On Fri, 01 Apr 2011 09:14:03 +1100, Ben Finney wrote:

> Howdy all,
> 
> I want to inherit from a class, and define aliases for many of its
> attributes. 

Are these aliases of arbitrary aliases, or only of methods, as in your 
example below?


> How can I refer to “the attribute that will be available by
> name ‘spam’ once this class is defined”?

You might be able to use the descriptor protocol to do something like 
that, but otherwise I don't think you can. However, I note that your 
example isn't *quite* how you describe it above.


>     class Foo(object):
>         def spam(self):
>             pass
>         def eggs(self):
>             pass
> 
>     class Bar(Foo):
>         beans = Foo.spam
>         mash = Foo.eggs

This assigns the name Bar.beans to the method object Foo.spam. If you now 
rebind the name Foo.spam to something else, Bar.beans will not likewise 
change, but will continue to refer to the original. This is contrary to 
your earlier description, where Bar.beans should also change.

This is no different from the usual Python namespace behaviour:

x = 42
y = x

y is an alias to x, until you rebind x. For variables, you can't change 
the behaviour; for attributes of a class, you may be able to write a 
descriptor to do something along those lines.


> Is that the right way to do it? Will that leave me open to “unbound
> method” or “is not an instance of ‘Bar’” or other problems when using
> ‘Bar.beans’?

I don't believe so. So long as you don't rebind the "alias" or the 
original, you should be fine.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#2325

FromBen Finney <ben+python@benfinney.id.au>
Date2011-04-01 11:59 +1100
Message-ID<878vvuokfw.fsf@benfinney.id.au>
In reply to#2319
Steven D'Aprano <steve+comp.lang.python@pearwood.info> writes:

> On Fri, 01 Apr 2011 09:14:03 +1100, Ben Finney wrote:
>
> > I want to inherit from a class, and define aliases for many of its
> > attributes.
>
> Are these aliases of arbitrary aliases, or only of methods, as in your
> example below?

I'd like to know how to do either, for making API wrapper classes.

> > How can I refer to “the attribute that will be available by
> > name ‘spam’ once this class is defined”?
>
> You might be able to use the descriptor protocol to do something like
> that, but otherwise I don't think you can. However, I note that your
> example isn't *quite* how you describe it above.

Yes, I got the names wrong. The example is accurate to what I'm meaning
to say.

> >     class Foo(object):
> >         def spam(self):
> >             pass
> >         def eggs(self):
> >             pass
> > 
> >     class Bar(Foo):
> >         beans = Foo.spam
> >         mash = Foo.eggs
>
> This assigns the name Bar.beans to the method object Foo.spam. If you
> now rebind the name Foo.spam to something else, Bar.beans will not
> likewise change, but will continue to refer to the original. This is
> contrary to your earlier description, where Bar.beans should also
> change.

Hmm. I think I can live with that limitation.

> > Is that the right way to do it? Will that leave me open to “unbound
> > method” or “is not an instance of ‘Bar’” or other problems when
> > using ‘Bar.beans’?
>
> I don't believe so. So long as you don't rebind the "alias" or the 
> original, you should be fine.

Okay, thank you.

-- 
 \      “I am too firm in my consciousness of the marvelous to be ever |
  `\       fascinated by the mere supernatural …” —Joseph Conrad, _The |
_o__)                                                     Shadow-Line_ |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#2321

FromCalvin Spealman <ironfroggy@gmail.com>
Date2011-03-31 20:36 -0400
Message-ID<mailman.57.1301618196.2990.python-list@python.org>
In reply to#2307
Sounds like you're just going to end up with more confusing code
having multiple ways to refer to the exact same thing. Why?

On Thu, Mar 31, 2011 at 6:14 PM, Ben Finney <ben+python@benfinney.id.au> wrote:
> Howdy all,
>
> I want to inherit from a class, and define aliases for many of its
> attributes. How can I refer to “the attribute that will be available by
> name ‘spam’ once this class is defined”?
>
>    class Foo(object):
>        def spam(self):
>            pass
>
>        def eggs(self):
>            pass
>
>    class Bar(Foo):
>        beans = Foo.spam
>        mash = Foo.eggs
>
> Is that the right way to do it? Will that leave me open to “unbound
> method” or “is not an instance of ‘Bar’” or other problems when using
> ‘Bar.beans’?
>
> --
>  \           “If [a technology company] has confidence in their future |
>  `\      ability to innovate, the importance they place on protecting |
> _o__)     their past innovations really should decline.” —Gary Barnett |
> Ben Finney
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://techblog.ironfroggy.com/
Follow me if you're into that sort of thing: http://www.twitter.com/ironfroggy

[toc] | [prev] | [next] | [standalone]


#2324

FromBen Finney <ben+python@benfinney.id.au>
Date2011-04-01 11:57 +1100
Message-ID<87d3l6okk1.fsf@benfinney.id.au>
In reply to#2321
Calvin Spealman <ironfroggy@gmail.com> writes:

> Sounds like you're just going to end up with more confusing code
> having multiple ways to refer to the exact same thing. Why?

(Why did you top-post?)

I'm defining aliases to conform to an existing API. The “Foo” class's
attributes are what is needed, but not by the right names. So I'm making
a subclass “Bar” to provide those same attributes by the names required
by the third-party API.

-- 
 \      “He that loveth father or mother more than me is not worthy of |
  `\        me: and he that loveth son or daughter more than me is not |
_o__)                worthy of me.” —Jesus, as quoted in Matthew 10:37 |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#2331

FromRaymond Hettinger <python@rcn.com>
Date2011-03-31 19:24 -0700
Message-ID<787d36b9-e31d-4b61-a14e-770337cfc280@a11g2000pro.googlegroups.com>
In reply to#2307
On Mar 31, 3:14 pm, Ben Finney <ben+pyt...@benfinney.id.au> wrote:
> Howdy all,
>
> I want to inherit from a class, and define aliases for many of its
> attributes. How can I refer to “the attribute that will be available by
> name ‘spam’ once this class is defined”?
>
>     class Foo(object):
>         def spam(self):
>             pass
>
>         def eggs(self):
>             pass
>
>     class Bar(Foo):
>         beans = Foo.spam
>         mash = Foo.eggs
>
> Is that the right way to do it?

For methods, that will work just fine.  For attributes, you will need
to make @property accessors that get and set the underlying attribute.


Raymond

[toc] | [prev] | [next] | [standalone]


#2342

FromJean-Michel Pichavant <jeanmichel@sequans.com>
Date2011-04-01 11:54 +0200
Message-ID<mailman.68.1301651655.2990.python-list@python.org>
In reply to#2331
Raymond Hettinger wrote:
> On Mar 31, 3:14 pm, Ben Finney <ben+pyt...@benfinney.id.au> wrote:
>   
>> Howdy all,
>>
>> I want to inherit from a class, and define aliases for many of its
>> attributes. How can I refer to “the attribute that will be available by
>> name ‘spam’ once this class is defined”?
>>
>>     class Foo(object):
>>         def spam(self):
>>             pass
>>
>>         def eggs(self):
>>             pass
>>
>>     class Bar(Foo):
>>         beans = Foo.spam
>>         mash = Foo.eggs
>>
>> Is that the right way to do it?
>>     
>
> For methods, that will work just fine.  For attributes, you will need
> to make @property accessors that get and set the underlying attribute.
>
>
> Raymond
>   
For attributes you could also override __getattribute__ & __setattr__ to 
wrap Bar's names into Foo's names.
Could work also for methods, but for methods your current idea is much 
more simple.

class Foo(object):
    def __init__(self):
       self.spam = 'someSpam'
       self.eggs = 'fewEggs'

    def vanilla(self):
        return self.spam

class Bar(Foo):
    _map = {
       'beans': 'spam',
       'mash': 'eggs',
       'chocolate': 'vanilla',
    }
    def __getattribute__(self, attribute):
        getSafely = object.__getattribute__
        _map =  getSafely(self, '_map')
        if attribute in _map:
            return getSafely(self, _map[attribute])
        else:
            return getSafely(self, attribute)


Bar().chocolate()
'someSpam'

Bar().mash
'fewEggs'

JM

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web