473,396 Members | 2,034 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

class declaration shortcut

I've come across a code snippet in www.rubyclr.com where they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)

I tried something like this, but it's nothing close to what I'd like:

def klass(table, *args):
cls = new.classobj(table, (), {})
for i in args:
setattr(cls, i, i)
return cls

But this above is not what I want.
I guess I should find a way to include the constructor code inside
this function, but I don't know if this is possible.
Also, I wonder if there is a way to use the variable name in order to
create a class with the same name (as in "Person"above).

Well, if anyone has an idea, I'd like to know...

Luis

Feb 28 '07 #1
28 1669
Luis M. González a écrit :
I've come across a code snippet in www.rubyclr.com where they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)
s/struct/Struct/
I tried something like this, but it's nothing close to what I'd like:

def klass(table, *args):
cls = new.classobj(table, (), {})
for i in args:
setattr(cls, i, i)
return cls

But this above is not what I want.
I guess I should find a way to include the constructor code inside
this function, but I don't know if this is possible.
Also, I wonder if there is a way to use the variable name in order to
create a class with the same name (as in "Person"above).

Well, if anyone has an idea, I'd like to know...
Here's a *very* Q&D attempt - that doesn't solve the name problem:
def Struct(name, *attribs):
args = ", ".join("%s=None" % attr for attr in attribs)
body = "\n ".join("self.%s = %s" % (attr, attr) \
for attr in attribs)
source = ("""
class %s(object):
def __init__(self, %s):
%s
""".strip()) % (name, args, body)
#print source
code = compile(source, 'dummy', 'single')
exec code
return locals()[name]

But note that I'd immediatly fire anyone using such an abomination in
production code.

Feb 28 '07 #2
Luis M. González wrote:
I've come across a code snippet in www.rubyclr.com where they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)
How about something like::

class Person(Record):
__slots__ = 'name', 'birthday', 'children'

You can then use the class like::

person = Person('Steve', 'April 25', [])
assert person.name == 'Steve'
assert person.birthday == 'April 25'
assert not person.children

Is that what you were looking for? If so, the recipe for the Record
class is here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/502237

STeVe
Feb 28 '07 #3
On Feb 28, 6:21 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Luis M. González wrote:
I've come across a code snippet inwww.rubyclr.comwhere they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.
The code is as follows:
Person = struct.new( :name, :birthday, :children)

How about something like::

class Person(Record):
__slots__ = 'name', 'birthday', 'children'

You can then use the class like::

person = Person('Steve', 'April 25', [])
assert person.name == 'Steve'
assert person.birthday == 'April 25'
assert not person.children

Is that what you were looking for? If so, the recipe for the Record
class is here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/502237

STeVe


Hmmm... not really.
The code above is supposed to be a shorter way of writing this:

class Person:
def __init__(self, name, birthday, children):
self.name = name
self.birthday = birthday
self.children = children

So the purpose of this question is finding a way to emulate this with
a single line and minimal typing.

There are a few problems here:
1) How to get the variable name (in this case "Person") become the
name of the class without explicity indicating it.
2) How to enter attribute names not enclosed between quotes. The only
way I can do it is by entering them as string literals.

It's not that I desperately need it, but I'm just curious about it...

Luis
Feb 28 '07 #4
Luis M. González wrote:
On Feb 28, 6:21 pm, Steven Bethard <steven.beth...@gmail.comwrote:
>How about something like::

class Person(Record):
__slots__ = 'name', 'birthday', 'children'

You can then use the class like::

person = Person('Steve', 'April 25', [])
assert person.name == 'Steve'
assert person.birthday == 'April 25'
assert not person.children

Is that what you were looking for? If so, the recipe for the Record
class is here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/502237
[snip]
Hmmm... not really.
The code above is supposed to be a shorter way of writing this:

class Person:
def __init__(self, name, birthday, children):
self.name = name
self.birthday = birthday
self.children = children

So the purpose of this question is finding a way to emulate this with
a single line and minimal typing.
That __init__ is exactly what was generated in my example above. So
you're mainly objecting to using two-lines? You can make it a one-liner
by writing::

class Person(Record): __slots__ = 'name', 'birthday', 'children'
1) How to get the variable name (in this case "Person") become the
name of the class without explicity indicating it.
The only things that know about their own names are class statements
(through metaclasses) so you can't really do it without a class
statement of some sort (which means you'll have to use two lines).
2) How to enter attribute names not enclosed between quotes. The only
way I can do it is by entering them as string literals.
If you're really bothered by quotes, a pretty minimal modification to
the recipe could generate the same code from:

class Person(Record): slots = 'name birthday children'

STeVe
Feb 28 '07 #5
Luis M. González wrote:
I've come across a code snippet in www.rubyclr.com where they show
how easy it is to declare a class compared to equivalent code in
c#. I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)
What's easy about this?

Also, this is a definition and not just a declaration.
But this above is not what I want.
I guess I should find a way to include the constructor code inside
this function, but I don't know if this is possible.
Could you please describe what exactly you want in an abstract way?
Also, I wonder if there is a way to use the variable name in order
to create a class with the same name (as in "Person"above).
Two classes with the same name?

In Python, classes have no name. They are anonymous objects which
can be bound to names.

Regards,
Björn

--
BOFH excuse #367:

Webmasters kidnapped by evil cult.

Feb 28 '07 #6
Bjoern Schliessmann a écrit :
(snip)
In Python, classes have no name.
class Toto(object):
pass

print Toto.__name__

Feb 28 '07 #7
Bruno Desthuilliers wrote:
class Toto(object):
pass

print Toto.__name__
Okay, I revoke my statement and assert the opposite.

But what's it (__name__) good for?

Regards,
Björn

--
BOFH excuse #179:

multicasts on broken packets

Mar 1 '07 #8
In <54*************@mid.individual.net>, Bjoern Schliessmann wrote:
Bruno Desthuilliers wrote:
>class Toto(object):
pass

print Toto.__name__

Okay, I revoke my statement and assert the opposite.

But what's it (__name__) good for?
As objects don't know to which name they are bound, that's a good way to
give some information in stack traces or when doing introspection.

Ciao,
Marc 'BlackJack' Rintsch
Mar 1 '07 #9
On Mar 1, 9:40 am, Marc 'BlackJack' Rintsch <bj_...@gmx.netwrote:
In <54msaoF21c6h...@mid.individual.net>, Bjoern Schliessmann wrote:
But what's it (__name__) good for?

As objects don't know to which name they are bound, that's a good way to
give some information in stack traces or when doing introspection.
Also, the name is used by pickle to find the class of pickled
instances.

Michele Simionato

Mar 1 '07 #10
Michele Simionato wrote:
On Mar 1, 9:40 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net>
>In <54msaoF21c6h...@mid.individual.net>, Bjoern Schliessmann
>>But what's it (__name__) good for?

As objects don't know to which name they are bound, that's a good
way to give some information in stack traces or when doing
introspection.

Also, the name is used by pickle to find the class of pickled
instances.
Mh. I suspect there's also more to it than I see now, but this
__name__ seems quite useless to me. What if I rebind the class'
name after definition? Or is it really just for some manual
introspection? If it is, it seems a bit of an overkill to me.
>>class Spam(object):
.... pass
....
>>Ham = Spam
Spam = 0
test = Ham()
test.__class__
<class '__main__.Spam'>
>>test.__class__.__name__
'Spam'
>>Spam
0
>>>
Regards,
Björn

--
BOFH excuse #137:

User was distributing pornography on server; system seized by FBI.

Mar 1 '07 #11
In <54*************@mid.individual.net>, Bjoern Schliessmann wrote:
Michele Simionato wrote:
>On Mar 1, 9:40 am, Marc 'BlackJack' Rintsch <bj_...@gmx.net>
>>In <54msaoF21c6h...@mid.individual.net>, Bjoern Schliessmann
>>>But what's it (__name__) good for?

As objects don't know to which name they are bound, that's a good
way to give some information in stack traces or when doing
introspection.

Also, the name is used by pickle to find the class of pickled
instances.

Mh. I suspect there's also more to it than I see now, but this
__name__ seems quite useless to me. What if I rebind the class'
name after definition?
Then it's a way to still get the name of the definition via `__name__`.
Together with the name of the module where the definition took place which
is also available as attribute on the objects it is very useful to find
out where to look for the source code. Just see the default `repr()` of
class objects.
Or is it really just for some manual introspection? If it is, it seems a
bit of an overkill to me.
>>>class Spam(object):
... pass
...
>>>Ham = Spam
Spam = 0
test = Ham()
test.__class__
<class '__main__.Spam'>
What would you expect this to look like if there weren't a __name__
attribute?

Ciao,
Marc 'BlackJack' Rintsch
Mar 1 '07 #12
On 28 Feb 2007 13:53:37 -0800, Luis M. González <lu*****@gmail.comwrote:
Hmmm... not really.
The code above is supposed to be a shorter way of writing this:

class Person:
def __init__(self, name, birthday, children):
self.name = name
self.birthday = birthday
self.children = children

So the purpose of this question is finding a way to emulate this with
a single line and minimal typing.
I believe this is what you are looking for:
http://aspn.activestate.com/ASPN/Coo.../Recipe/361668

olle = attrdict(name = "Olle", birthday = date(2222, 12, 1), children = 329)
print olle.name, olle.birthday, olle.children

It is not identical to the Ruby recipe, but is IMHO better. Being able
to instantiate objects on the fly, without having to explicitly
declare the class, is a big advantage.

--
mvh Björn
Mar 1 '07 #13
On Feb 28, 7:26 pm, "Luis M. González" <luis...@gmail.comwrote:
I've come across a code snippet inwww.rubyclr.comwhere they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)

I tried something like this, but it's nothing close to what I'd like:

def klass(table, *args):
cls = new.classobj(table, (), {})
for i in args:
setattr(cls, i, i)
return cls

But this above is not what I want.
I guess I should find a way to include the constructor code inside
this function, but I don't know if this is possible.
Also, I wonder if there is a way to use the variable name in order to
create a class with the same name (as in "Person"above).

Well, if anyone has an idea, I'd like to know...

Luis
Perhaps something like:

class Struct(object):
def __init__(self, **vals):
for slot, val in vals.iteritems():
setattr(self, slot, val)
def __repr__(self):
return "%s(%s)" % (type(self).__name__,
", ".join("%s=%s" % (slot, repr(getattr(self, slot))) for
slot in self.__slots__ if hasattr(self, slot)))

def new_struct(name, *slots):
return type(name, (Struct,), {'__slots__': slots})
Then you can do:
>>Point = new_struct('Point', 'x', 'y')
p=Point(x=1, y=2)
p
Point(x=1, y=2)
>>p.x
1
>>p.y
2
>>p.x=7
p
Point(x=7, y=2)
>>Person = new_struct('Person', 'name', 'tel', 'email')
jack = Person(name='Jack')
jack
Person(name='Jack')
>>jack.tel='555-132'
jack
Person(name='Jack', tel='555-132')
>>>
etc...

Of course that's if you want a c-like struct. Otherwise there's not
much point at all!

--
Arnaud
Mar 1 '07 #14
Arnaud Delobelle wrote:
On Feb 28, 7:26 pm, "Luis M. González" <luis...@gmail.comwrote:
>I've come across a code snippet inwww.rubyclr.comwhere they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

The code is as follows:

Person = struct.new( :name, :birthday, :children)

I tried something like this, but it's nothing close to what I'd like:

def klass(table, *args):
cls = new.classobj(table, (), {})
for i in args:
setattr(cls, i, i)
return cls

But this above is not what I want.
I guess I should find a way to include the constructor code inside
this function, but I don't know if this is possible.
Also, I wonder if there is a way to use the variable name in order to
create a class with the same name (as in "Person"above).

Well, if anyone has an idea, I'd like to know...

Luis

Perhaps something like:

class Struct(object):
def __init__(self, **vals):
for slot, val in vals.iteritems():
setattr(self, slot, val)
def __repr__(self):
return "%s(%s)" % (type(self).__name__,
", ".join("%s=%s" % (slot, repr(getattr(self, slot))) for
slot in self.__slots__ if hasattr(self, slot)))

def new_struct(name, *slots):
return type(name, (Struct,), {'__slots__': slots})
Then you can do:
>>>Point = new_struct('Point', 'x', 'y')
p=Point(x=1, y=2)
p
Point(x=1, y=2)
>>>p.x
1
>>>p.y
2
>>>p.x=7
p
Point(x=7, y=2)
>>>Person = new_struct('Person', 'name', 'tel', 'email')
jack = Person(name='Jack')
jack
Person(name='Jack')
>>>jack.tel='555-132'
jack
Person(name='Jack', tel='555-132')
This does pretty much the same thing as the recipe I posted:

http://aspn.activestate.com/ASPN/Coo.../Recipe/502237

Note that your approach requires repetition of the 'Person' and quotes
around each attribute name, which the OP complained about. The recipe at
least gets rid of the repetition of 'Person'.

You might also want to check out Raymond Hettinger's NamedTuple recipe:

http://aspn.activestate.com/ASPN/Coo.../Recipe/500261

STeVe
Mar 1 '07 #15
On Mar 1, 4:01 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Arnaud Delobelle wrote:
[...]
This does pretty much the same thing as the recipe I posted:
Not at all. My new_struct create returns a new class which is similar
to a C struct (notice the __slots__). The recipe you refer to is
nothing more a class which can be initialised with some attributes. It
does not address the OP's question at all.
http://aspn.activestate.com/ASPN/Coo.../Recipe/502237

Note that your approach requires repetition of the 'Person' and quotes
around each attribute name, which the OP complained about. The recipe at
least gets rid of the repetition of 'Person'.
The 'name' argument is not necessary. It is just here to give a user-
friendly name to the newly created class.
One could just as well write the new_struct function so that
>>Person = new_struct('name', 'tel', ...)
Of course it would be impossible for the function written as above to
name the class in a user-meaningful way. The recipe you refer to does
not face this problem because it is not a method to quickly create a
new class, it is merely a class whose __init__ method allows you to
initialise some attribute at instance-creation time.

As for the quotes around the attribute names, well... Let's say that
if it was possible to do without, I don't think I would be using
python...

--
Arnaud

Mar 1 '07 #16
Arnaud Delobelle wrote:
On Mar 1, 4:01 pm, Steven Bethard <steven.beth...@gmail.comwrote:
>Arnaud Delobelle wrote:
[...]
>This does pretty much the same thing as the recipe I posted:

Not at all. My new_struct create returns a new class which is similar
to a C struct (notice the __slots__). The recipe you refer to is
nothing more a class which can be initialised with some attributes. It
does not address the OP's question at all.
> http://aspn.activestate.com/ASPN/Coo.../Recipe/502237
Huh? It uses __slots__ in almost exactly the same way. If you just
s/Struct/Record in your ``new_struct`` function, you'll get essentially
the same behavior, except that if you use the recipe, you'll get an
__init__ that handles positional arguments, and displays better help::
>>def new_struct(name, *slots):
... return type(name, (Struct,), {'__slots__': slots})
...
>>Person = new_struct('Person', 'name')
Person('Bob')
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: __init__() takes exactly 1 argument (2 given)
>>Person(name='Bob')
Person(name='Bob')
>>help(Person.__init__)
Help on method __init__ in module __main__:

__init__(self, **vals) unbound __main__.Person method
>>def new_struct(name, *slots):
... return type(name, (Record,), {'__slots__': slots})
...
>>Person = new_struct('Person', 'name')
Person('Bob')
Person(name='Bob')
>>help(Person.__init__)
Help on method __init__:

__init__(self, name) unbound records.Person method
Maybe I'm not understanding you?

Steve
Mar 1 '07 #17
On Mar 1, 7:37 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Arnaud Delobelle wrote:
On Mar 1, 4:01 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Arnaud Delobelle wrote:
[...]
This does pretty much the same thing as the recipe I posted:
Not at all. My new_struct create returns a new class which is similar
to a C struct (notice the __slots__). The recipe you refer to is
nothing more a class which can be initialised with some attributes. It
does not address the OP's question at all.
http://aspn.activestate.com/ASPN/Coo.../Recipe/502237

Huh? It uses __slots__ in almost exactly the same way.
I'm sorry I somehow got my hyperlinks mixed up and though you were
refering to

http://aspn.activestate.com/ASPN/Coo.../Recipe/361668

which was mentioned by someone else on this thread. If I had seen
yours I wouldn't have posted this. So my comment on you link was
completely erroneous as, as you are pointing out, the functionality of
my code snippet and your link are very similar. Mine was only a proof
of concept bit of code, so yours is more polished.

Although I don't see the necessity of a metaclass: you could have

class Record(object):
def __init__(self, *vals):
for slot, val in zip(self.__slots__, vals):
setattr(self, slot, val)
# And the other methods

if you want positional slots initialisation. I chose keyword
arguments in mine because I though it would be a good idea to be able
not to initialise some of them at object instanciation.

--
Arnaud

Mar 1 '07 #18
Arnaud Delobelle wrote:
>>> http://aspn.activestate.com/ASPN/Coo.../Recipe/502237
[snip]
Although I don't see the necessity of a metaclass: you could have

class Record(object):
def __init__(self, *vals):
for slot, val in zip(self.__slots__, vals):
setattr(self, slot, val)
# And the other methods

if you want positional slots initialisation. I chose keyword
arguments in mine
You could certainly do it that way, but note that the one with the
metaclass not only allows *either* positional or keyword arguments, but
also displays better help messages -- using the *vals or **vals code,
help() will tell you something like:

__init__(self, **vals)

while using the metaclass-generated __init__, help() will tell you the
more informative:

__init__(self, name)

(Or whatever signature is appropriate given the __slots__.) So no, it's
not necessary, but it does have a few advantages.

STeVe
Mar 1 '07 #19
On Mar 1, 3:03 pm, "Arnaud Delobelle" <arno...@googlemail.comwrote:
On Mar 1, 4:01 pm, Steven Bethard <steven.beth...@gmail.comwrote:
Arnaud Delobelle wrote:
[...]
This does pretty much the same thing as the recipe I posted:

Not at all. My new_struct create returns a new class which is similar
to a C struct (notice the __slots__). The recipe you refer to is
nothing more a class which can be initialised with some attributes. It
does not address the OP's question at all.
http://aspn.activestate.com/ASPN/Coo.../Recipe/502237
Note that your approach requires repetition of the 'Person' and quotes
around each attribute name, which the OP complained about. The recipe at
least gets rid of the repetition of 'Person'.

The 'name' argument is not necessary. It is just here to give a user-
friendly name to the newly created class.
One could just as well write the new_struct function so that
>Person = new_struct('name', 'tel', ...)

Of course it would be impossible for the function written as above to
name the class in a user-meaningful way. The recipe you refer to does
not face this problem because it is not a method to quickly create a
new class, it is merely a class whose __init__ method allows you to
initialise some attribute at instance-creation time.

As for the quotes around the attribute names, well... Let's say that
if it was possible to do without, I don't think I would be using
python...

--
Arnaud


This is the closest we got so far to the intended result.
If there was a way to enter attributes without quotes, it would be
almost identical.
Anyway, I wonder if the code comparison in www.rubuclr.com between the
c# and ruby code is fair...
As far as I know, classes and structs are not the same thing.
In the case of that ruby example, can someone add methods later?

Luis
Mar 1 '07 #20
Luis M. González wrote:
This is the closest we got so far to the intended result.
If there was a way to enter attributes without quotes, it would be
almost identical.
Ok, below is the Python code so that the following works::

class Person(Struct): "name birthday children"

Note that
* The "Person" name is not repeated
* The attribute names are not individually quoted
* It's two characters shorter than the Ruby code::

Person = Struct.new(:name, :birthday, :children)

Is that good enough? ;-)

STeVe

class InitFromSlots(type):
def __new__(meta, name, bases, bodydict):
slots = bodydict.get('__doc__', '').split()
bodydict.setdefault('__slots__', slots)
if slots and '__init__' not in bodydict:
parts = ['def __init__(self, %s):' % ', '.join(slots)]
for slot in slots:
parts.append(' self.%s = %s' % (slot, slot))
exec '\n'.join(parts) in bodydict
super_new = super(InitFromSlots, meta).__new__
return super_new(meta, name, bases, bodydict)

class Struct(object):
__metaclass__ = InitFromSlots
__slots__ = ()
def _items(self):
for name in self.__slots__:
yield name, getattr(self, name)
def __repr__(self):
args = ', '.join('%s=%r' % tup for tup in self._items())
return '%s(%s)' % (type(self).__name__, args)
def __iter__(self):
for name in self.__slots__:
yield getattr(self, name)
def __getstate__(self):
return dict(self._items())
def __setstate__(self, statedict):
self.__init__(**statedict)
Mar 1 '07 #21
On Thu, 01 Mar 2007 10:44:48 +0100, Bjoern Schliessmann wrote:
Mh. I suspect there's also more to it than I see now, but this
__name__ seems quite useless to me. What if I rebind the class'
name after definition? Or is it really just for some manual
introspection? If it is, it seems a bit of an overkill to me.
Overkill? Storage of a single attribute holding a (usually short) string
is overkill?

The thing to remember is that the link between names and objects in
Python is one-way only. Names (by definition) have to know which object
they are bound to. But objects don't know what name, or names, (if any)
are bound to themselves. Yes, they *could* keep a list of the names bound
to them, but that would be a lot of work at runtime for little benefit.

So if you rebind a name, the objects can't tell. And generally you
wouldn't want them to. Something like the following is rightfully quite
rare:
>>int
<type 'int'>
>>int.__name__
'int'
>>foo = int; int = "something else"
type(0) # Do you expect <type 'foo'>?
<type 'int'>
>>int
'something else'

Normally the reason for rebinding classes, functions etc. are (1) to save
typing and (2) an optimization to save name look-ups.

# slow way
for item in sequence:
package.module.function(item)

# faster way
f = package.module.function
for item in sequence:
f(item)

When you do that, you wouldn't expect the __name__ of some.module.function
to change to f, and it doesn't.

The downside is that on the rare corner case where you do want the
__name__ of an object to change, it doesn't.

--
Steven D'Aprano

Mar 2 '07 #22
Steven D'Aprano wrote:
Overkill? Storage of a single attribute holding a (usually short)
string is overkill?
No, but storing the first name a class is bound to in it is a bit
of, IMHO.
When you do that, you wouldn't expect the __name__ of
some.module.function to change to f, and it doesn't.
But what is it for then? =) Showing the first name the class was
bound to?

Regards,
Björn

--
BOFH excuse #217:

The MGs ran out of gas.

Mar 2 '07 #23
On Mar 2, 3:01 pm, Bjoern Schliessmann <usenet-
mail-0306.20.chr0n...@spamgourmet.comwrote:
Steven D'Aprano wrote:
Overkill? Storage of a single attribute holding a (usually short)
string is overkill?

No, but storing the first name a class is bound to in it is a bit
of, IMHO.
Don't see it as the first name a class is bound to, but rather as the
name a class is defined as.
If class_object.__name__ == 'Foo' it means that somewhere in your code
there is a class definition:

class Foo:
# stuff

Same for function: if function_object.__name__ == 'bar' it means that
somewhere you have

def bar(...):
# stuff

(Of course this is not the case if you use another way to define
functions or classes, e.g. type() )
When you do that, you wouldn't expect the __name__ of
some.module.function to change to f, and it doesn't.

But what is it for then? =) Showing the first name the class was
bound to?
What I described above is quite useful I think. The alternative
(anonymous classes) is that given an object myobj you have no means to
find out what its class is (by that I mean to be able to locate the
class definition in your source code), apart from stabbing in the dark
(i.e. trying type(myobj)==someclass until successful).

--
Arnaud

Mar 2 '07 #24
Arnaud Delobelle wrote:
Don't see it as the first name a class is bound to, but rather as
the name a class is defined as.
If class_object.__name__ == 'Foo' it means that somewhere in your
code there is a class definition:

class Foo:
# stuff

Same for function: if function_object.__name__ == 'bar' it means
that somewhere you have

def bar(...):
# stuff

(Of course this is not the case if you use another way to define
functions or classes, e.g. type() )
This is somehow contrary to my understanding of the Python names
concept.

What if I use a loop to define several classes based on data --
they'll all have the same __name__ unless I change it manually.

Having this __name__ attribute set seems to me like "magic behind
the lines" which Python strives to evade, doesn't it? Personally,
I'd prefer inserting a mechanism for this manually if and when I
really need the functionality, but see below.
What I described above is quite useful I think. The alternative
(anonymous classes) is that given an object myobj you have no
means to find out what its class is (by that I mean to be able to
locate the class definition in your source code), apart from
stabbing in the dark (i.e. trying type(myobj)==someclass until
successful).
In the typical case where you have one name per class definition,
yes.

Perhaps I'm lacking a typical application of __name__; that must be
why I'm so stubborn here ;)

Regards,
Björn

--
BOFH excuse #419:

Repeated reboots of the system failed to solve problem

Mar 2 '07 #25
On Mar 2, 8:28 pm, Bjoern Schliessmann <usenet-
mail-0306.20.chr0n...@spamgourmet.comwrote:
This is somehow contrary to my understanding of the Python names
concept.

What if I use a loop to define several classes based on data --
they'll all have the same __name__ unless I change it manually.
Well that's not a typical way of defining classes. It is then your
job to name those classes.
Having this __name__ attribute set seems to me like "magic behind
the lines" which Python strives to evade, doesn't it? Personally,
I'd prefer inserting a mechanism for this manually if and when I
really need the functionality, but see below.
So you want a Class object without a __name__, and then you would
subclass it to NamedClass with a __name__.
OTOH every class that you define in python using the 'class' keyword
has an obvious name (the identifier that follows the 'class' keyword),
so it seems natural to me to endow each defined class with a __name__.
What I described above is quite useful I think. The alternative
(anonymous classes) is that given an object myobj you have no
means to find out what its class is (by that I mean to be able to
locate the class definition in your source code), apart from
stabbing in the dark (i.e. trying type(myobj)==someclass until
successful).

In the typical case where you have one name per class definition,
yes.
As you say this is the typical case, and a __name__ attribute is very
useful in this case. For the minority of cases when you have a class
factory for example, then I guess it is your responsibility to name
the class appropriately.

IMHO if you create classes in a way that makes it impossible to name
them naturally, then it is likely that you are misusing the class
object.
Perhaps I'm lacking a typical application of __name__; that must be
why I'm so stubborn here ;)
Here are 3 (please correct me if I'm wrong)
>>class Foo: pass
Foo # typical application 1
<class __main__.Foo at 0x136ef30>
>>foo=Foo()
foo # typical application 2
<__main__.Foo instance at 0x1372788>
>>pickle.dumps(foo) # typical application 3
'(i__main__\nFoo\np0\n(dp1\nb.'

--
Arnaud

Mar 2 '07 #26
On Feb 28, 1:26 pm, "Luis M. González" <luis...@gmail.comwrote:
I've come across a code snippet in www.rubyclr.com where they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.
I posted like 10 minutes ago, but it looks like it didn't go through.
The ruby code is not an easy way to declare a class, it is a ruby
class for creating c-like struct objects.

This is the basic idea behind the ruby Struct class (but this is quick
and dirty, the real implementation is different and done in c, but you
should get the basic idea):

class Struct2
def initialize(*args)
@@attrs = []
args.each { |arg|
eval("class << self; attr_accessor :#{arg} end")
@@attrs.push(arg)
}
end
def new(*args)
args.each_index { |i|
eval("self.#{@@attrs[i]}=args[i]")
return self
}
end
end

Person = Struct2.new(:name)
bob = Person.new('bob')
puts bob.name
A python equiv. would be something like:

class Struct():
def __init__(self, *args):
self.attrs = []
for arg in args:
setattr(self, arg, None)
self.attrs.append(arg)
def __call__(self, *args):
for i in range(len(args)):
setattr(self, self.attrs[i], args[i])
return self

Person = Struct('name')
bob = Person('bob')
print bob.name

Regards,
Jordan

Mar 2 '07 #27
On Mar 2, 8:29 pm, "MonkeeSage" <MonkeeS...@gmail.comwrote:
On Feb 28, 1:26 pm, "Luis M. González" <luis...@gmail.comwrote:
I've come across a code snippet inwww.rubyclr.comwhere they show how
easy it is to declare a class compared to equivalent code in c#.
I wonder if there is any way to emulate this in Python.

I posted like 10 minutes ago, but it looks like it didn't go through.
The ruby code is not an easy way to declare a class, it is a ruby
class for creating c-like struct objects.

This is the basic idea behind the ruby Struct class (but this is quick
and dirty, the real implementation is different and done in c, but you
should get the basic idea):

class Struct2
def initialize(*args)
@@attrs = []
args.each { |arg|
eval("class << self; attr_accessor :#{arg} end")
@@attrs.push(arg)
}
end
def new(*args)
args.each_index { |i|
eval("self.#{@@attrs[i]}=args[i]")
return self
}
end
end

Person = Struct2.new(:name)
bob = Person.new('bob')
puts bob.name

A python equiv. would be something like:

class Struct():
def __init__(self, *args):
self.attrs = []
for arg in args:
setattr(self, arg, None)
self.attrs.append(arg)
def __call__(self, *args):
for i in range(len(args)):
setattr(self, self.attrs[i], args[i])
return self

Person = Struct('name')
bob = Person('bob')
print bob.name

Regards,
Jordan

Thanks for your detailed reply!
So after all, the www.rubyclr.com code is not a fair comparison.
Because the c# code shows a class definition, and the ruby code shows
a struct definition, which is not equivalent to a class.
Is that right?

Mar 2 '07 #28
On Mar 2, 5:48 pm, "Luis M. González" <luis...@gmail.comwrote:
Thanks for your detailed reply!
So after all, the www.rubyclr.com code is not a fair comparison.
Because the c# code shows a class definition, and the ruby code shows
a struct definition, which is not equivalent to a class.
Is that right?
Well c sharp has a struct type, but it's basically just a class, so in
that sense the comparison is accurate. But I don't think the ruby code
is supposed to be a one to one comparison (you could write a similar
Struct class in c sharp too). I assume that what the author there was
trying to say was that ruby is a higher-level language / has more
syntactic sugar than c sharp many times. The same can be said of
python as well, though python is a bit more reserved about adding
sugar (ruby is more aligned with perl in TMTOWTDI, python is more like
"There should be one -- and preferably only one -- obvious way to do
it").

Regards,
Jordan

Mar 3 '07 #29

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

83
by: Alexander Zatvornitskiy | last post by:
Hello All! I'am novice in python, and I find one very bad thing (from my point of view) in language. There is no keyword or syntax to declare variable, like 'var' in Pascal, or special syntax in...
5
by: Xiangliang Meng | last post by:
Hi, all. What are the benefit and the drawback of defining a class embedded inside another class? For example: class List { public:
4
by: I_AM_DON_AND_YOU? | last post by:
There is one more problem I am facing but didn't get the solution. In my Setup Program I am not been able to create 2 things (when the program is intalled on the client machine ) : (1) create...
23
by: mark.moore | last post by:
I know this has been asked before, but I just can't find the answer in the sea of hits... How do you forward declare a class that is *not* paramaterized, but is based on a template class? ...
3
by: Mike Edgewood | last post by:
Is there a simple way, shortcut, or macro to create a property skeletons? I would live to be able to type a name and a type and have the property created based on that info. Private...
4
by: zfareed | last post by:
#include <iostream> #include <fstream> using namespace std; template<class ItemType> class SortedList { private:
9
by: Jess | last post by:
Hello, I was told that if I declare a static class constant like this: class A{ static const int x = 10; }; then the above statement is a declaration rather than a definition. As I've...
2
by: gasfusion | last post by:
Hey guys! I'm having some issues with one of my installer packages i compiled with Microsoft Visual Studio 2005. (VB installer is buggy as hell and wouldn't work on half of our machines no matter...
1
by: mahesh.kanakaraj | last post by:
Dear All, I have a question to ask about the validity of a complexType declaration. Lets say an element declaration inside a schema looks like this.... <element name="abc" type="abcType"> ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.