overriding setting

  • Thread starter Francesco Guerrieri
  • Start date
F

Francesco Guerrieri

Hello,
this is my first post to the list :) I've looked around a bit before
asking, and since I haven't found... I'm here to ask my question.

I'm trying to ovveride attribute setting, but I haven't still found
the right way to use all the fancy __get__, __set__ and
__getattribute__ :)

I would like to retain initialization of an object by use of the = and
not as a function call. A simple example is this:

I want to define an "enhanced" list class, whose items will be other
(built in) lists and providing a "padding" method which fills all the
contained lists to the same lenght.
An example could be:

class myList(list):
def __init__(self):
self._max = None
list.__init__(self)
def pad(self):
for item in self:
if type(item)== list:
while len(item) < self._max:
item.append("")

Now the question is this:
I would like to initialize such an object in this way:
a = myList()
a = [[1, 2, 3], [4, 5, 6, 7]]
a.pad()
# and now a _should_ contain [[1, 2, 3, ""], [4, 5, 6, 7]]


Obviously this doesn't work, because when at the second line I do the
initialization, type(a) becomes <type 'list'>, and so I get the
expected AttributeError since pad cannot be found.

A possible solution could be to create a container class, intercepting
every attribute accession with __getattribute__.
In this case I should refer to Container.myFirstList,
Container.mySecondList, which is ugly because of the need to refer to
Container first...(not to mention that I'm still working on making the
__getattribute__ work properly... :) )


Do you have any suggestions? or maybe I should simply stop trying to
do that and resort to adding some sort of insert or append method
(this is what I have done for the time being, but I found this
solution less appealing and nice ...)

thanks in advance,
Francesco
--
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as
both victim and villain by the vicissitudes of fate. This visage, no
mere veneer of vanity, is a vestige of the vox populi, now vacant,
vanished. However, this valorous visitation of a bygone vexation
stands vivified, and has vowed to vanquish these venal and virulent
vermin vanguarding vice and vouchsafing the violently vicious and
voracious violation of volition. The only verdict is vengeance; a
vendetta held as a votive, not in vain, for the value and veracity of
such shall one day vindicate the vigilant and the virtuous. Verily,
this vichyssoise of verbiage veers most verbose vis-à-vis an
introduction, so let me simply add that it's my very good honor to
meet you and you may call me V." -- V's introduction to Evey
 
M

Marc 'BlackJack' Rintsch

Now the question is this:
I would like to initialize such an object in this way:
a = myList()
a = [[1, 2, 3], [4, 5, 6, 7]]
a.pad()
# and now a _should_ contain [[1, 2, 3, ""], [4, 5, 6, 7]]


Obviously this doesn't work, because when at the second line I do the
initialization, type(a) becomes <type 'list'>, and so I get the
expected AttributeError since pad cannot be found.

You don't initialize in the second line, you just rebind `a` to a
completely different object. Names don't have types in Python, objects do.

`list()` takes an optional argument. Just make sure your derived type
does to and passes this to the base class `__init__()`. Then you can
create an instance like this:

a = MyList([[1, 2, 3], [4, 5, 6, 7]])

Ciao,
Marc 'BlackJack' Rintsch
 
F

Francesco Guerrieri

Now the question is this:
I would like to initialize such an object in this way:
a = myList()
a = [[1, 2, 3], [4, 5, 6, 7]]
a.pad()
# and now a _should_ contain [[1, 2, 3, ""], [4, 5, 6, 7]]


Obviously this doesn't work, because when at the second line I do the
initialization, type(a) becomes <type 'list'>, and so I get the
expected AttributeError since pad cannot be found.

You don't initialize in the second line, you just rebind `a` to a
completely different object. Names don't have types in Python, objects do.

`list()` takes an optional argument. Just make sure your derived type
does to and passes this to the base class `__init__()`. Then you can
create an instance like this:

a = MyList([[1, 2, 3], [4, 5, 6, 7]])

yes it's true that it is not an initialization :) It's that I hoped
that there was a way to do an init rather than a rebinding of the
name.
Your suggestion is exactly what I have implemented for the time being...
I subclass the builtin list type, I have a pad method which adds the
requested whitespaces at the end, an append method which invokes the
base class append AND calls the pad method, and finally a __call__
which calls the append. Furthermore, I check that the input is
valid... So everything works fine :)

The only problem is that while coding I have the temptation to write a
= [[...], [...]) rather than a([1, 2, 3], [5,6, 7, 8]). Plus I find
it uglier :) but if there isn't a reasonable way, I'll give up :)

thanks,
Francesco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top