a fairly ugly/kludgy way to get 'aliases' in Python
Bengt Richter
bokr at oz.net
Fri Jan 17 20:07:37 EST 2003
On 17 Jan 2003 10:12:45 -0800, Cliff Wells <LogiplexSoftware at earthlink.net> wrote:
>On Thu, 2003-01-16 at 15:52, Jonathan P. wrote:
>class A:
>> def __init__(self):
>> self.long_descriptive_name=0
>> self.long_descriptive_name2=10
>>
>> def x(self):
>> D_=self.__dict__
>> alias1='long_descriptive_name'
>> alias2='long_descriptive_name2'
>> D_[alias]=D_[alias2]*D_[alias1]
^^^^^--would have to be alias1 to correspond to next 2 lines
>> # instead of self.long_descriptive_name =
>> # self.long_descriptive_name*self.long_descriptive_name2
D_[alias1]=D_[alias1]*D_[alias2] # to correspond to above 2 lines
Note that the order in the preceding line is different from your alias version.
It might seem like a nit, but if you are multiplying matrices it's not.
>>
>> Question:
>> Will the dictionary lookup 'D_[alias]' impose a
>> performance penalty versus 'self.long_descriptive_name' or
>> will the compiler do the same thing internally anyway in
>> both cases?
>
>I don't think performance will be affected either way (it's all
>dictionary lookups). Still, I wonder why you don't just use:
If anything, it might be a shade faster since attribute logic must
do a little work before getting to the __dict__ he's specifying directly.
>
>class A:
> def __init__(self):
> self.long_descriptive_name = 0
> self.long_descriptive_name2 = 10
>
> def x(self):
> alias1 = self.long_descriptive_name
> alias2 = self.long_descriptive_name2
> self.alias = alias2 * alias1
>
>which would seem to be the equivalent, more readable form.
>
Not quite equivalent. You are binding self.alias with the result,
and he is binding self.<whatever the string value of alias is supposed to be>
(Except I think it was a typo and either his alias1 was supposed to be alias or vice versa).
If you want to do table-driven aliasing in another way, look at the x method below, yet note
that the actual values are stored with the long-name attributes (as seen with vars(a)).
Of course, I'm not sure what all this is about ;-)
===< t_alias.py >==============
class Aliaser(type):
def __new__(cls, name, bases, cdict):
for alias, orig in cdict['__rw_aliases__']:
d = {'alias':alias, 'orig':orig}
exec ("""\
def _get_%(alias)s(self): return self.%(orig)s
def _set_%(alias)s(self, v): self.%(orig)s = v
%(alias)s = property(_get_%(alias)s, _set_%(alias)s)
""" % d) in cdict
return type.__new__(cls, name, bases, cdict)
class A(object):
__metaclass__ = Aliaser
__rw_aliases__ = [
('alias1', 'long_descriptive_name'),
('alias2', 'long_descriptive_name2')
]
def __init__(self):
self.long_descriptive_name = 1
self.long_descriptive_name2 = 10
def x(s):
s.alias1 = s.alias2 * s.alias1
if __name__ == '__main__':
a = A()
print A, '=>', a
for i in range(3):
print 'alias1=%-4s alias2=%-4s %s' % (a.alias1, a.alias2, vars(a))
a.x()
===============================
Maybe the long descriptive stuff belongs in doc strings and/or help material
if it's just going to clutter things.
Here's what the output looks like:
[17:12] C:\pywk\meta>t_alias.py
<class '__main__.A'> => <__main__.A object at 0x007DCFE0>
alias1=1 alias2=10 {'long_descriptive_name': 1, 'long_descriptive_name2': 10}
alias1=10 alias2=10 {'long_descriptive_name': 10, 'long_descriptive_name2': 10}
alias1=100 alias2=10 {'long_descriptive_name': 100, 'long_descriptive_name2': 10}
Regards,
Bengt Richter
More information about the Python-list
mailing list