Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

class variable declarations...

2 views
Skip to first unread message

Lee John Moore

unread,
Jun 16, 2003, 9:15:33 AM6/16/03
to
Is using __init__() to force the setting of various class attributes really not
frowned upon? Or is there another way of doing this that's considered more
acceptable?

class SpeedTouchComm:
"Interface with the SpeedTouch router"
def __init__(self, connect, uid, pwd, rtuid, rtpwd):
self.connect = connect
self.uid = uid
self.pwd = pwd
self.rtuid = rtuid
self.rtpwd = rtpwd

It just seems against the law to be creating instances of SpeedTouchComm and
accessing class attributes that aren't even referred to outside the __init__()
function.

My biggest mental block with python seems to be undeclared variables. A
declaration block alone is handy for reference. Statically typed languages
have really messed me up. Is there a therapy group for refugees? ;-)
--
"However far you may travel in this world, you
will still occupy the same volume of space."
- Traditional Ur-Bororo saying

Alan Kennedy

unread,
Jun 16, 2003, 10:13:34 AM6/16/03
to
Lee John Moore wrote:

> My biggest mental block with python seems to be undeclared variables. A
> declaration block alone is handy for reference. Statically typed
> languages have really messed me up. Is there a therapy group for
> refugees? ;-)

How about this, using new style classes:-

class SpeedTouchComm(object):


"Interface with the SpeedTouch router"

__slots__ = ['connect', 'uid', 'pwd', 'rtuid', 'rtpwd']



def __init__(self, connect, uid, pwd, rtuid, rtpwd):
self.connect = connect
self.uid = uid
self.pwd = pwd
self.rtuid = rtuid
self.rtpwd = rtpwd

self.namenotinslots = ''

>>> o = SpeedTouchComm(1,2,3,4,5)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 12, in __init__
AttributeError: 'SpeedTouchComm' object has no attribute 'namenotinslots'
>>>

There are more sophisticated ways to manipulate object instances and data, for
example using descriptors or __metaclasses__. But I think that this mostly
solves your difficulty.

HTH,

--
alan kennedy
-----------------------------------------------------
check http headers here: http://xhaus.com/headers
email alan: http://xhaus.com/mailto/alan

Peter Hansen

unread,
Jun 16, 2003, 10:32:41 AM6/16/03
to
Lee John Moore wrote:
>
> Is using __init__() to force the setting of various class attributes really not
> frowned upon? Or is there another way of doing this that's considered more
> acceptable?
>
> class SpeedTouchComm:
> "Interface with the SpeedTouch router"
> def __init__(self, connect, uid, pwd, rtuid, rtpwd):
> self.connect = connect
> self.uid = uid
> self.pwd = pwd
> self.rtuid = rtuid
> self.rtpwd = rtpwd
>
> It just seems against the law to be creating instances of SpeedTouchComm and
> accessing class attributes that aren't even referred to outside the __init__()
> function.

Not sure what you mean here. "Class attributes" would normally mean
attributes that are shared by all instances of a class, as if you
were to do "SpeedTouchComm.rtuid = rtuid" in the above, instead of
using "self" which refers to an *instance*, not the class.

Also, what do you mean by "against the law"? The above example seems
to be exactly how *all* Python code works, where you pass values in
to the __init__ method and it dutifully assigns them to various names
in self. I don't think you're being clear, sorry.

Maybe the short answer will do: there's nothing wrong with the above.
It even exhibits good coding style! :-)

-Peter

Lee John Moore

unread,
Jun 16, 2003, 11:41:26 AM6/16/03
to
One may as well begin with Peter Hansen's letter to comp.lang.python:
[..]

>>
>> class SpeedTouchComm:
>> "Interface with the SpeedTouch router"
>> def __init__(self, connect, uid, pwd, rtuid, rtpwd):
>> self.connect = connect
>> self.uid = uid
>> self.pwd = pwd
>> self.rtuid = rtuid
>> self.rtpwd = rtpwd
[..]

I've left the example in for reference. :-)

> Not sure what you mean here. "Class attributes" would
> normally mean attributes that are shared by all instances of a
> class, as if you were to do "SpeedTouchComm.rtuid = rtuid" in
> the above, instead of using "self" which refers to an
> *instance*, not the class.

I know. I'm referring to connect, uid, pwd, etc. as attributes
of the SpeedTouchComm class. I referred to them as variables in
a previous post (simply because I would refer to them as
declared variables in a similar OP or C++ class), but I was told
I should be calling them attributes. So that's where that came
from. :-)

> Also, what do you mean by "against the law"?

I'm trying and failing at being humorous. ;-) What didn't 'feel'
like good code is compounded by my difficulty in coming to terms
with a language that doesn't require me to declare everything.
The above example just doesn't feel very clean (to me), but then
you consider it good coding style so I'm clearly just having
difficulty adapting. ;-)

> to be exactly how *all* Python code works, where you pass
> values in to the __init__ method and it dutifully assigns them
> to various names in self. I don't think you're being clear,
> sorry.
>
> Maybe the short answer will do: there's nothing wrong with the
> above. It even exhibits good coding style! :-)

Phew. You're clearer and more concise than I'll ever be. Thank
ye kindly for saying that. Did I mention that I love Python?
And I've only been studying it on and off for ten days. Even my
cron jobs have been ported just for the hell of it. ;-)

Lee John Moore

unread,
Jun 16, 2003, 11:52:31 AM6/16/03
to
One may as well begin with Alan Kennedy's letter to comp.lang.python:
[..]
>
> There are more sophisticated ways to manipulate object
> instances and data, for example using descriptors or
> __metaclasses__. But I think that this mostly solves your
> difficulty.

I'd almost given up on the idea of limiting the list of class
attributes. __slots__ changes all of that. Thanks for
mentioning it! :-)

Peter Hansen

unread,
Jun 16, 2003, 12:00:44 PM6/16/03
to
Lee John Moore wrote:
>
> One may as well begin with Peter Hansen's letter to comp.lang.python:
> [..]
> >>
> >> class SpeedTouchComm:
> >> "Interface with the SpeedTouch router"
> >> def __init__(self, connect, uid, pwd, rtuid, rtpwd):
> >> self.connect = connect
> >> self.uid = uid
> >> self.pwd = pwd
> >> self.rtuid = rtuid
> >> self.rtpwd = rtpwd
> [..]
>
> I've left the example in for reference. :-)
>
> > Not sure what you mean here. "Class attributes" would
> > normally mean attributes that are shared by all instances of a
> > class, as if you were to do "SpeedTouchComm.rtuid = rtuid" in
> > the above, instead of using "self" which refers to an
> > *instance*, not the class.
>
> I know. I'm referring to connect, uid, pwd, etc. as attributes
> of the SpeedTouchComm class. I referred to them as variables in
> a previous post (simply because I would refer to them as
> declared variables in a similar OP or C++ class), but I was told
> I should be calling them attributes. So that's where that came
> from. :-)

Hmm... they're *not* class attributes though. Or at least, not
how I use the term. They are instance attributes, or merely
unadorned "attributes". Calling them class attributes confuses
them with, for example, the capitalized constant I've added in
the following example:

class SpeedTouchComm:
"Interface with the SpeedTouch router"

DEFAULT_PORT = 577

def __init__(self, connect, uid, pwd, rtuid, rtpwd):
self.connect = connect
self.uid = uid
self.pwd = pwd
self.rtuid = rtuid
self.rtpwd = rtpwd


If some code wanted to refer to this constant, it could access it
as simply "self.DEFAULT_PORT" or, if it needed to change it (often
a bad idea, for a constant!) it would have to do this:

SpeedTouchComm.DEFAULT_PORT = 566

or, sometimes better, sometimes worse:

self.__class__.DEFAULT_PORT = 566

*All* instances that are created automatically have access to this
shared value because it is a *class* attribute, rather than an
instance attribute. All the items prefixed with self. are instance
attributes, and pertain only to a single instance of a class,
never to all instances.

(The self.__class__ example above might be confusing but I left
it in as it does have times where it is a "better" way to write
the previous line.)

-Peter

Lee John Moore

unread,
Jun 16, 2003, 12:22:11 PM6/16/03
to
One may as well begin with Peter Hansen's letter to comp.lang.python:
[..]

Pardon the snipping. I'm a bit worried about leaving too much
in for the sake of mailing list bandwidth. :)

[..]


> *All* instances that are created automatically have access to
> this shared value because it is a *class* attribute, rather
> than an instance attribute. All the items prefixed with self.
> are instance attributes, and pertain only to a single instance
> of a class, never to all instances.

You've helped me realise where I misunderstood the original
respondent. It's only obvious after reading your message
though. Thanks for explaining. Much appreciated. :)

Aahz

unread,
Jun 16, 2003, 12:39:45 PM6/16/03
to
[You'll need a fixed-width font for this]

In article <3EEDD08E...@hotmail.com>,


Alan Kennedy <ala...@hotmail.com> wrote:
>
>How about this, using new style classes:-
>
>class SpeedTouchComm(object):
> "Interface with the SpeedTouch router"
>
> __slots__ = ['connect', 'uid', 'pwd', 'rtuid', 'rtpwd']

____ ___ _ _ _ _____ ____ ___ _____ _ _ _ _____
| _ \ / _ \| \ | ( )_ _| | _ \ / _ \ |_ _| | | | / \|_ _|
| | | | | | | \| |/ | | | | | | | | | | | | |_| | / _ \ | |
| |_| | |_| | |\ | | | | |_| | |_| | | | | _ |/ ___ \| |
|____/ \___/|_| \_| |_| |____/ \___/ |_| |_| |_/_/ \_\_|

__slots__ are strictly an optimization technique; you *will* have
problems with subclasses of SpeedTouchComm unless you're *very* careful.
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"If you don't know what your program is supposed to do, you'd better not
start writing it." --Dijkstra

Michele Simionato

unread,
Jun 16, 2003, 1:42:31 PM6/16/03
to
Alan Kennedy <ala...@hotmail.com> wrote in message news:<3EEDD08E...@hotmail.com>...

A recent thread (google is your friend) pointed out that __slots__ should
NOT be used as a way of declaring variables.

It is much better if you use descriptors or metaclasses. Here is
a (little tested) solution:

class UndeclaredNameError(Exception): pass

class WithDeclaredNames(type):
def __init__(cls,name,bases,dic):
declared=getattr(cls,'declared')
def setattr(self,k,v):
if k in declared:
object.__setattr__(self,k,v)
else:
raise UndeclaredNameError(k)
if declared is not None: cls.__setattr__=setattr


class SpeedTouchComm(object):
"Interface with the SpeedTouch router"

__metaclass__=WithDeclaredNames
declared = ['connect', 'uid', 'pwd', 'rtuid', 'rtpwd']



def __init__(self, connect, uid, pwd, rtuid, rtpwd):
self.connect = connect
self.uid = uid
self.pwd = pwd
self.rtuid = rtuid
self.rtpwd = rtpwd
self.namenotinslots = ''

o = SpeedTouchComm(1,2,3,4,5)

Traceback (most recent call last):

File "<stdin>", line 28, in ?
File "<stdin>", line 26, in __init__
File "<stdin>", line 11, in setattr
__main__.UndeclaredNameError: namenotinslots

Ben Finney

unread,
Jun 16, 2003, 7:51:50 PM6/16/03
to
On 16 Jun 2003 16:22:11 GMT, Lee John Moore wrote:
> Pardon the snipping. I'm a bit worried about leaving too much
> in for the sake of mailing list bandwidth. :)

You've done exactly right: only quote the part of the message that
you are responding to.

--
\ "If you're a cowboy and you're dragging a guy behind your |
`\ horse, I bet it would really make you mad if you looked back |
_o__) and the guy was reading a magazine." -- Jack Handey |
http://bignose.squidly.org/ 9CFE12B0 791A4267 887F520C B7AC2E51 BD41714B

0 new messages