Re: Items inheriting attributes from its container?

2009-08-25 Thread Kreso
Jan Kaliszewski z...@chopin.edu.pl wrote:
[...]


Great! Thanks to all of you for advices and code.

K.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Items inheriting attributes from its container?

2009-08-24 Thread Bruno Desthuilliers

Kreso a écrit :

I would like to create a list-like container class so that, additionally
to usual list methods, I could attach attributes to the container instances.
However, I would like it so that the items contained in the particular
instance of container somehow 'inherit' those attributes i.e.

cont = Container()
cont.color = 'blue'
cont.append(item)
print item.color
'blue'



This is named environmental aquisition (or simply aquisition) and is 
one of the base mechanisms in Zope 2. While an interesting idea, from 
experience, it can rapidly turn into a total maintainance nightmare if 
not used with care :-/


--
http://mail.python.org/mailman/listinfo/python-list


Re: Items inheriting attributes from its container?

2009-08-22 Thread Christian Heimes

Kreso schrieb:

I would like to create a list-like container class so that, additionally
to usual list methods, I could attach attributes to the container instances.
However, I would like it so that the items contained in the particular
instance of container somehow 'inherit' those attributes i.e.


The Python web application framework Zope implements the feature under 
the name acquisition. Happy Googling!


Christian

--
http://mail.python.org/mailman/listinfo/python-list


Re: Items inheriting attributes from its container?

2009-08-22 Thread Stephen Fairchild
Kreso wrote:

 I would like to create a list-like container class so that, additionally
 to usual list methods, I could attach attributes to the container
 instances. However, I would like it so that the items contained in the
 particular instance of container somehow 'inherit' those attributes i.e.
 
 cont = Container()
 cont.color = 'blue'
 cont.append(item)
 print item.color
 'blue'
 
 The example appended below does that, but with the restriction that
 container attributes must be set in the instantiation phase. This is
 actually fine for me at the moment because my objects are read only, but
 I would like to hear about better solutions, with more flexibility,
 please.
 
 
 #-8
 class Player:
 Class for items
 
 def __init__(self, playerdata, team):
 self.data = playerdata
 for key in team.__dict__:
 setattr(self, key, team.__dict__[key])
 return
 
 
 class Team(list):
 Class for containers
 
 def __init__(self, teamdata, playerdata):
 for key in teamdata:
 setattr(self, key, teamdata[key])
 for item in playerdata:
 self.append(Player(item, self))
 return
 
 
 lakersdata = {'name' : 'Lakers', 'kitcolor' : 'yellow'}
 lakersplayers = [['Kobe', 'PG', 12, 123], ['Kareem', 'FW', 23, 345]]
 
 lakers = Team(lakersdata, lakersplayers)
 
 # This is fine:
 p1 = lakers[1]
 print p1.kitcolor
 
 # However the following doesn't work:
 lakers.kitcolor = 'blue'
 print p1.kitcolor
 
 #-8

I hope this gives you some good ideas.

http://en.wikipedia.org/wiki/Join_(SQL)

I suspect you will be finding a use for the special __getattr__ method,
which is called when an attribute is not found. This can be used to search
on your set of joined objects. Your list of joined objects should be a
set() to prevent duplicates.
-- 
Stephen Fairchild
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Items inheriting attributes from its container?

2009-08-22 Thread Jan Kaliszewski

23-08-2009 Kreso kkumernott...@thatfamoussearchenginesmail.com wrote:


I would like to create a list-like container class so that, additionally
to usual list methods, I could attach attributes to the container  
instances.

However, I would like it so that the items contained in the particular
instance of container somehow 'inherit' those attributes i.e.

cont = Container()
cont.color = 'blue'
cont.append(item)
print item.color
'blue'


[snip]


class Player:
Class for items

def __init__(self, playerdata, team):
self.data = playerdata
for key in team.__dict__:
setattr(self, key, team.__dict__[key])
return


class Team(list):
Class for containers
   def __init__(self, teamdata, playerdata):
for key in teamdata:
setattr(self, key, teamdata[key])
for item in playerdata:
self.append(Player(item, self))
return

lakersdata = {'name' : 'Lakers', 'kitcolor' : 'yellow'}
lakersplayers = [['Kobe', 'PG', 12, 123], ['Kareem', 'FW', 23, 345]]

lakers = Team(lakersdata, lakersplayers)


[snip]


p1 = lakers[1]
print p1.kitcolor


[snip]


lakers.kitcolor = 'blue'
print p1.kitcolor


[Not tested. I believe that the idea is clear]


  class RecruitmentError(ValueError):
  Raised when a player cannot be recruited.


  class Player(object):
  A potential item of a Team() instance.

  def __init__(self, playerdata, team=None):
  self.data = playerdata
  self.team = None
  if team:
  team.append(self)

  # (called when the usual attribute lookup didn't succeed)
  def __getattr__(self, name):
  return getattr(self.team, name)

  # ^ the last method may not be necessary -- you can always
  #   access to team data via 'team' attribute
  #   (and 'explicit is better than implicit')


  class Team(list):
  A container for Player() instances.

  def __init__(self, teamdata, playerdata=None):
  for key in teamdata:
  setattr(self, key, teamdata[key])
  for data in playerdata:
  self.append(Player(data))

  def _validate_and_get(self, index=None, player=None):
  if player is not None and not isinstance(player, Player):
  raise TypeError('A Player instance is required')
  if index is not None:
  if isinstance(index, slice):
  raise TypeError('Slicing is not allowed')
  return self[index]  # (raise IndexError for bad index)

  _validate = _validate_and_get

  def _recruit(self, player):
  if player.team is None:
  player.team = self
  else:
  raise RecruitmentError('Player %s has already recruited')

  def _dismiss(self, player):
  player.team = None

  def __setitem__(self, index, player):
  current = self._validate_and_get(index, player)
  if player is not current:
  self._recruit(player)
  self._dismiss(current)
  list.__setitem__(self, index, player)

  def __delitem__(self, index):
  player = self._validate_and_get(index)
  self._dismiss(player)
  list.__delitem__(self, index)

  def append(self, player):
  self._validate(player=player)
  self._recruit(player)
  list.append(self, player)

  # and similarly:
  # * def extend...
  # * def insert...
  # * def pop...
  # * def remove...

...if you really need ordered container (reflecting functions/hierarchy
of players in a team?).

Otherwise, as Stephen noted, you should subclass set rather than list.

Cheers,
*j

--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list


Re: Items inheriting attributes from its container?

2009-08-22 Thread Jan Kaliszewski

PS. Erratum:


   class Team(list):
   A container for Player() instances.

   def __init__(self, teamdata, playerdata=None):


*** Here should be added: list.__init__(self) ***


   for key in teamdata:
   setattr(self, key, teamdata[key])
   for data in playerdata:
   self.append(Player(data))


--
Jan Kaliszewski (zuo) z...@chopin.edu.pl
--
http://mail.python.org/mailman/listinfo/python-list