Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old August 13th, 2008, 05:45 PM
eliben
Guest
 
Posts: n/a
Default Factory for Struct-like classes

Hello,

I want to be able to do something like this:

Employee = Struct(name, salary)

And then:

john = Employee('john doe', 34000)
print john.salary

Basically, Employee = Struct(name, salary) should be equivalent to:

class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary

Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?

Thanks in advance

P.S. I'm aware of this common "pattern":

class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)

Which allows:

john = Struct(name='john doe', salary=34000)
print john.salary

But what I'm asking for is somewhat more general.


  #2  
Old August 13th, 2008, 06:35 PM
Michele Simionato
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Aug 13, 6:43 pm, eliben <eli...@gmail.comwrote:
Quote:
Hello,
>
I want to be able to do something like this:
>
Employee = Struct(name, salary)
>
And then:
>
john = Employee('john doe', 34000)
print john.salary
>
Basically, Employee = Struct(name, salary) should be equivalent to:
>
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
>
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Thanks in advance
>
P.S. I'm aware of this common "pattern":
>
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
>
Which allows:
>
john = Struct(name='john doe', salary=34000)
print john.salary
>
But what I'm asking for is somewhat more general.

NamedTuples: http://code.activestate.com/recipes/303439/
  #3  
Old August 13th, 2008, 06:45 PM
Christian Heimes
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

eliben wrote:
Quote:
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?

Try named tuple http://code.activestate.com/recipes/500261/

A named tuple implementation is part of Python 2.6 and 3.0. For older
versions of Python use the recipe from activestate.

Christian

  #4  
Old August 13th, 2008, 06:55 PM
eliben
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Aug 13, 7:30*pm, Christian Heimes <li...@cheimes.dewrote:
Quote:
eliben wrote:
Quote:
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Try named tuplehttp://code.activestate.com/recipes/500261/
>
A named tuple implementation is part of Python 2.6 and 3.0. For older
versions of Python use the recipe from activestate.
>
Christian
Thanks Christian - this is exactly what I've been looking for.
Some thoughts...

1) I see this is done with exec anyway, so there's no more pythonic
way.

2) The definition of fields as a single string is weird. Why not use
**kwargs instead ?
  #5  
Old August 13th, 2008, 07:15 PM
Marc Christiansen
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

eliben <eliben@gmail.comwrote:
Quote:
Hello,
>
I want to be able to do something like this:
>
Employee = Struct(name, salary)
>
And then:
>
john = Employee('john doe', 34000)
print john.salary
>
Basically, Employee = Struct(name, salary) should be equivalent to:
>
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
>
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Thanks in advance
I have some old code laying around which should do what you want. It was
originally written by Kragen Sitaker in 2001-10-16 and is public domain.

def defstruct(*fields):
class Struct(object):
def __init__(self, *contents):
if len(contents) != len(self.structfields):
raise TypeError(
"wrong number of arguments: expected %d %s, got %d" %
(len(self.structfields),
repr(self.structfields),
len(contents)))
for field, content in zip(self.structfields, contents):
setattr(self, field, content)
Struct.structfields = fields
return Struct

Use:
Employee = defstruct("name", "salary")
john = Employee('john doe', 34000)
print john.salary

Marc
  #6  
Old August 14th, 2008, 04:25 PM
Larry Bates
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

eliben wrote:
Quote:
Hello,
>
I want to be able to do something like this:
>
Employee = Struct(name, salary)
>
And then:
>
john = Employee('john doe', 34000)
print john.salary
>
Basically, Employee = Struct(name, salary) should be equivalent to:
>
class Employee(object):
def __init__(self, name, salary):
self.name = name
self.salary = salary
>
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Thanks in advance
>
P.S. I'm aware of this common "pattern":
>
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
>
Which allows:
>
john = Struct(name='john doe', salary=34000)
print john.salary
>
But what I'm asking for is somewhat more general.
>
>
That's about as "general" as it gets ;-). It works for any number/type of
attribute. I would probably make it a new-style class by subclassing object,
but for simulating a generic row container, this is quite good. You might
extend it with a __str__ method, __len__ method, make it an iterator, etc.
but that is quite easy.

-Larry

  #7  
Old August 15th, 2008, 03:35 AM
Matthew Wilson
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Thu 14 Aug 2008 11:19:06 AM EDT, Larry Bates wrote:
Quote:
eliben wrote:
Quote:
>Hello,
>>
>I want to be able to do something like this:
>>
>Employee = Struct(name, salary)
>>
>And then:
>>
>john = Employee('john doe', 34000)
>print john.salary
I find something like this useful, especially if any time I tried to
cram in an attribute that wasn't allowed, the class raises an exception.

One way to do it is to make a function that defines a class inside and
then returns it. See the code at the end of this post for an example.

I couldn't figure out how to do this part though:
Quote:
Quote:
>Employee = Struct(name, salary)
I have to do this instead (notice that the args are strings):
Quote:
Quote:
>Employee = Struct('name', 'salary')
Anyway, here's the code:

def struct_maker(*args):

class C(object):
arglist = args
def __init__(self, *different_args):

# Catch too few/too many args.
if len(self.arglist) != len(different_args):
raise ValueError("I need exactly %d args (%s)"
% (len(self.arglist), list(self.arglist)))

for a, b in zip(self.arglist, different_args):
setattr(self, a, b)

def __setattr__(self, k, v):
"Prevent any attributes except the first ones."
if k in self.arglist:
object.__setattr__(self, k, v)
else:
raise ValueError("%s ain't in %s"
% (k, list(self.arglist)))

return C

And here it is in action:

In [97]: Employee = struct_maker('name', 'salary')

In [98]: matt = Employee('Matt Wilson', 11000)

In [99]: matt.name, matt.salary

Out[99]: ('Matt Wilson', 11000)

In [100]: matt.invalid_attribute = 99
---------------------------------------------------------------------------
ValueError: invalid_attribute ain't in ['name', 'salary']


Matt
  #8  
Old August 18th, 2008, 10:25 AM
Gabriel Genellina
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On 13 ago, 14:46, eliben <eli...@gmail.comwrote:
Quote:
On Aug 13, 7:30*pm, Christian Heimes <li...@cheimes.dewrote:
>
Quote:
eliben wrote:
Quote:
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Quote:
Try named tuplehttp://code.activestate.com/recipes/500261/
>
1) I see this is done with exec anyway, so there's no more pythonic
way.
It doesn't *have* to be done with exec - I think there are other
variants using metaclasses instead.
Quote:
2) The definition of fields as a single string is weird. Why not use
**kwargs instead ?
Because the field ordering would be lost, which is important for a
named *tuple*.
(Anyway, I'd prefer a list of names instead of a single string...)

--
Gabriel Genellina
  #9  
Old August 18th, 2008, 04:35 PM
Dan Lenski
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Aug 13, 1:30*pm, Christian Heimes <li...@cheimes.dewrote:
Quote:
Trynamedtuplehttp://code.activestate.com/recipes/500261/
>
Anamedtupleimplementation is part of Python 2.6 and 3.0. For older
versions of Python use the recipe from activestate.
>
Christian
This named tuple recipe is pretty cool... I think there may be a
slight bug in the Python docs, though. The ActiveState page explains
that it avoids the overhead of a per-instance __dict__ by using the
__slots__ variable. However, according to the most-recent Python
docs, __slots__ does *NOT* work with subclasses of list, str, or
tuple.

From http://docs.python.org/ref/slots.html#l2h-222:

# __slots__ do not work for classes derived from ``variable-length''
built-in types such as long, str and tuple.

On the other hand, nametuple does appear to work as advertised.
Quote:
Quote:
Quote:
>>Person=namedtuple.namedtuple('Person', ('name', 'age', 'height'))
>>p=Person('Bob', 24, 1.86)
>>p.name
'Bob'
Quote:
Quote:
Quote:
>>p.shoe_size
AttributeError: 'Person' object has no attribute 'shoe_size'
Quote:
Quote:
Quote:
>>p.__dict__
AttributeError: 'Person' object has no attribute '__dict__'

So is there a bug in the Python docs? Does __slots__ in fact work
with subclasses of tuple?

Dan
  #10  
Old August 19th, 2008, 04:45 PM
eliben
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Aug 18, 11:16*am, Gabriel Genellina <gagsl-...@yahoo.com.arwrote:
Quote:
On 13 ago, 14:46, eliben <eli...@gmail.comwrote:
>
Quote:
On Aug 13, 7:30*pm, Christian Heimes <li...@cheimes.dewrote:
>
Quote:
Quote:
eliben wrote:
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Quote:
Quote:
Try named tuplehttp://code.activestate.com/recipes/500261/
>
Quote:
1) I see this is done with exec anyway, so there's no more pythonic
way.
>
It doesn't *have* to be done with exec - I think there are other
variants using metaclasses instead.
>
Can you suggest an alternative, without exec ?

Eli


  #11  
Old August 20th, 2008, 08:05 AM
Dan Lenski
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Mon, 18 Aug 2008 08:28:53 -0700, Dan Lenski wrote:
Quote:
So is there a bug in the Python docs? Does __slots__ in fact work with
subclasses of tuple?
>
Dan
Anybody think that this may actually be a mistake in the Python docs? Who
would I contact about getting them corrected?

Dan

  #12  
Old August 21st, 2008, 03:55 AM
Dave Benjamin
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

Christian Heimes wrote:
Quote:
eliben wrote:
Quote:
>Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
>does this. I suppose it can be done with 'exec', but is there a more
>Pythonic way ?
>
Try named tuple http://code.activestate.com/recipes/500261/
>
A named tuple implementation is part of Python 2.6 and 3.0. For older
versions of Python use the recipe from activestate.
Whaaa? Named tuples are being added to Python? Neat! Is there any
documentation on this? I can't seem to find anything on the web...

Thanks,
Dave
  #13  
Old August 21st, 2008, 06:15 AM
eliben
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

On Aug 21, 4:51*am, Dave Benjamin <ra...@lackingtalent.comwrote:
Quote:
Christian Heimes wrote:
Quote:
eliben wrote:
Quote:
Ruby's 'Scruct' class (http://ruby-doc.org/core/classes/Struct.html)
does this. I suppose it can be done with 'exec', but is there a more
Pythonic way ?
>
Quote:
Try named tuplehttp://code.activestate.com/recipes/500261/
>
Quote:
A named tuple implementation is part of Python 2.6 and 3.0. For older
versions of Python use the recipe from activestate.
>
Whaaa? Named tuples are being added to Python? Neat! Is there any
documentation on this? I can't seem to find anything on the web...
>
It's not easy to find unless you recall where you've seen it:
http://docs.python.org/dev/3.0/libra...ons.namedtuple

  #14  
Old August 21st, 2008, 06:25 AM
Dave Benjamin
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

eliben wrote:
Quote:
Quote:
>Whaaa? Named tuples are being added to Python? Neat! Is there any
>documentation on this? I can't seem to find anything on the web...
>
It's not easy to find unless you recall where you've seen it:
http://docs.python.org/dev/3.0/libra...ons.namedtuple
Thanks!
  #15  
Old August 21st, 2008, 08:45 AM
Gabriel Genellina
Guest
 
Posts: n/a
Default Re: Factory for Struct-like classes

En Tue, 19 Aug 2008 12:43:27 -0300, eliben <eliben@gmail.comescribió:
Quote:
On Aug 18, 11:16*am, Gabriel Genellina <gagsl-...@yahoo.com.arwrote:
Quote:
>On 13 ago, 14:46, eliben <eli...@gmail.comwrote:
>>
Quote:
On Aug 13, 7:30*pm, Christian Heimes <li...@cheimes.dewrote:
Try named tuplehttp://code.activestate.com/recipes/500261/
>>
Quote:
1) I see this is done with exec anyway, so there's no more pythonic
way.
>>
>It doesn't *have* to be done with exec - I think there are other
>variants using metaclasses instead.
>Can you suggest an alternative, without exec ?
See these recipes: http://code.activestate.com/recipes/303439/ and 303770
and 303481; read the comments section too.

--
Gabriel Genellina

 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles