By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,420 Members | 1,061 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,420 IT Pros & Developers. It's quick & easy.

Re: Understanding the pythonic way: why a.x = 1 is better thana.setX(1) ?

P: n/a
Sorry... pressed enter but really didn't want to.

As I said, let's say I have a class

class A:
def __init__(self):
self.x = None

Python makes the decision to allow the developers to directly access
the attribute "x", so that they can directly write: "a.x = 1", or
whatever; this has for me the unfortunate side effect that if I write,
for example "a.y = 1", when I really wanted to write "a.x = 1" no one
cares about it, and I'm unable to spot this error until later.

Of course, I know that while I'm fresh, I've a good knowledge of the
code, and anything else, I will be able to avoid such stupid errors;
however, I'm afraid of the times when I'm tired, when I have to put my
hands on the code of someone else, and so on.

Please, understand that I'm not stating that python is wrong... after
all, if it is wrong, I can move to a language like Java, which has a
different approach on it. I'm really very interested in reading past
discussion on it, if they are available.

Regards
Marco

On Thu, Sep 4, 2008 at 12:57 PM, Marco Bizzarri
<ma************@gmail.comwrote:
Let's say I've a class a, where I can write:

--
Marco Bizzarri
http://notenotturne.blogspot.com/
http://iliveinpisa.blogspot.com/


--
Marco Bizzarri
http://notenotturne.blogspot.com/
http://iliveinpisa.blogspot.com/
Sep 4 '08 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Of course, I know that while I'm fresh, I've a good knowledge of the
code, and anything else, I will be able to avoid such stupid errors;
however, I'm afraid of the times when I'm tired, when I have to put my
hands on the code of someone else, and so on.

Please, understand that I'm not stating that python is wrong... after
all, if it is wrong, I can move to a language like Java, which has a
different approach on it. I'm really very interested in reading past
discussion on it, if they are available.
This has not much to do with the question of setters and getters. Because in
your code you could write

def setX(self, x):
self.y = x

def getX(self):
return self.x

So the error occurs in the same way.

What you are essentially asking is: why is python dynamic instead of static?

Because *that* is what is the difference. In a static language, you need to
declare first what you want to be available, e.g. which variables and
methods are available and such.

Of course then the compiler (or whoever evaluates the static declarations)
can puke on you if you attempt a stunt like the one you describe.

Python (and other languages such as Ruby, Javascript) chose other. They give
you the freedom to add instance variables (or even methods) at will, with
the cost of the occasional error like the above.

OTOH, Java makes me write soooo much more code that me becoming tired and
doing some stupid mistake (and there are lots of them doable in static
languages as well, otherwise no C/C++ or Java-program would crash....)
becomes much more likely....YMMV.

Diez
Sep 4 '08 #2

P: n/a
Marco Bizzarri a crit :
Sorry... pressed enter but really didn't want to.

As I said, let's say I have a class

class A:
def __init__(self):
self.x = None

Python makes the decision to allow the developers to directly access
the attribute "x",
So do Java, if you make your attribute public (which would be a big
error given Java's lack of support for computed attribute, but this is
another problem).
so that they can directly write: "a.x = 1", or
whatever; this has for me the unfortunate side effect that if I write,
for example "a.y = 1", when I really wanted to write "a.x = 1" no one
cares about it,
I assume *you* do !-)

But this is barely related to having explicit setters or not - it comes
from the fact that the default[1] Python's object behaviour is to
support arbitrary attribute setting.

[1] some objects don't, but this is mostly for optimization reasons.
and I'm unable to spot this error until later.
Not sure, but IIRC tools like pylint or pychecker might be able to warn
you about this. But anyway :
Of course, I know that while I'm fresh, I've a good knowledge of the
code, and anything else, I will be able to avoid such stupid errors;
however, I'm afraid of the times when I'm tired, when I have to put my
hands on the code of someone else, and so on.
The edit/test cycle in Python is usually fast enough so you should spot
the problem *pretty* quickly. This is at least what I learned from 8+
years of python (and a couple other dynamic languages) programming...

Not to say that problems like the one you mention (or similar problems
with dynamic typing etc) never happens, nor that they're never painful
to track down and fix - just that they happen way less often than one
might fear, and are most of the time really quickly spotted and fixed.
Please, understand that I'm not stating that python is wrong... after
all, if it is wrong, I can move to a language like Java, which has a
different approach on it.
I don't think it's a matter of "right" or "wrong" - mostly a matter of
tradeoffs and balance. But if you go for static typing and (allegedly)
provable correctness, you may want to have a look at languages like OCaml.
I'm really very interested in reading past
discussion on it, if they are available.
Well... Most of these "discussions" alas boil down to bondage&discipline
proponants asserting - against all evidences - that dynamic languages
are unsafe and unusable for anything else than simple throw-away scripts
or toy projects, and dynamic proponants arguing - against all evidences
- that static typing and everything related is just a waste of time
(FWIW, you might find myself in the first camp until approx year 2k and
the second for the five or six following years). And sometimes, someone
a bit more sensible trying to take a more balanced approach to the
problem, usually to no avail.
Sep 4 '08 #3

P: n/a
On Thu, Sep 4, 2008 at 1:19 PM, Diez B. Roggisch <de***@nospam.web.dewrote:
>
What you are essentially asking is: why is python dynamic instead of static?
Most probably you're right. Maybe I will make a trip back to my
university books and take a look at them again :-)

Thanks
Marco

--
Marco Bizzarri
http://notenotturne.blogspot.com/
http://iliveinpisa.blogspot.com/
Sep 4 '08 #4

P: n/a
On Thu, Sep 4, 2008 at 4:39 PM, Marco Bizzarri <ma************@gmail.comwrote:
>
Most probably you're right. Maybe I will make a trip back to my
university books and take a look at them again :-)
Meant: you *are* right. Sorry.

Saluti
Marco

--
Marco Bizzarri
http://notenotturne.blogspot.com/
http://iliveinpisa.blogspot.com/
Sep 4 '08 #5

P: n/a
On Sep 4, 7:09*am, "Marco Bizzarri" <marco.bizza...@gmail.comwrote:
Sorry... pressed enter but really didn't want to.

As I said, let's say I have a class

class A:
* * def __init__(self):
* * * * *self.x = None

Python makes the decision to allow the developers to directly access
the attribute "x", *so that they can directly write: "a.x = 1", or
whatever; this has for me the unfortunate side effect that if I write,
for example "a.y = 1", when I really wanted to write "a.x = 1" no one
cares about it, and I'm unable to spot this error until later.

Of course, I know that while I'm fresh, I've a good knowledge of the
code, and anything else, I will be able to avoid such stupid errors;
however, I'm afraid of the times when I'm tired, when I have to put my
hands on the code of someone else, and so on.
So what happens in Java (or any language for that matter) if there are
indeed two attributes x and y with the same type and you mistype the
one for the other ? Or if you meant to write x-y instead of y-x ?

When coding tired or on someone's else code, stupid errors are the
ones you should worry the least about.

George
Sep 4 '08 #6

P: n/a
On Sep 4, 7:09 am, "Marco Bizzarri" <marco.bizza...@gmail.comwrote:
Sorry... pressed enter but really didn't want to.

As I said, let's say I have a class

class A:
def __init__(self):
self.x = None

Python makes the decision to allow the developers to directly access
the attribute "x", so that they can directly write: "a.x = 1", or
whatever; this has for me the unfortunate side effect that if I write,
for example "a.y = 1", when I really wanted to write "a.x = 1" no one
cares about it, and I'm unable to spot this error until later.

You can write code to guard against this if you want:

class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
Carl Banks
Sep 4 '08 #7

P: n/a
On 4 , 22:59, Carl Banks <pavlovevide...@gmail.comwrote:
You can write code to guard against this if you want:

class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x

I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.

Carl Banks
'__slots__' is better:
class A(object):
__slots__ = set(["x"])
def __init__(self, x):
self.y = x

this will do the same, only faster
>>A(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
AttributeError: 'A' object has no attribute 'y'
Ivan Illarionov
Sep 4 '08 #8

P: n/a
On 4 ֧ߧ, 21:49, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
Ivan Illarionov a crit :
On 4 ֧ߧ, 22:59, Carl Banks <pavlovevide...@gmail.comwrote:
You can write code to guard against this if you want:
class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
'__slots__' is better:

For which definition of "better" ? __slots__ are a mean to optimize
memory usage, not to restrict dynamism. Being able to dynamically add
arbitrary attributes is actually a feature, not a bug, and uselessly
restricting users from doing so is not pythonic. IOW : don't do that.
Carl's example is restricting dynamism in the same way as __slots__.
I've just suggested a better implementation. It is not me who
suggested dynamism restriction as a way to guard against errors.
Sep 4 '08 #9

P: n/a
On Sep 4, 3:15 pm, Ivan Illarionov <ivan.illario...@gmail.comwrote:
On 4 , 22:59, Carl Banks <pavlovevide...@gmail.comwrote:
You can write code to guard against this if you want:
class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" % attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
Carl Banks

'__slots__' is better:
class A(object):
__slots__ = set(["x"])
def __init__(self, x):
self.y = x

this will do the same, only faster>>A(1)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
AttributeError: 'A' object has no attribute 'y'

However, if you subclass your version of A that uses __slots__, the
subclass will once again allow all attribute access, whereas if you
subclass my version of A that uses __getattr__, it will still be
restricted to the allowed symbols (unless you were to override the
list of symbols, which you probably would).

The latter behavior is less surprising and less dangerous, which
(besides the questionable usage) is the main reason using __slots__ is
not recommended for this purpose.

(Having said that, I do admit to using __slots__ for this purpose
once. But, the confusing aspects of __slots__ were managed by a
metaclass and hidden from the user.)
Carl Banks
Sep 4 '08 #10

P: n/a
On Thu, Sep 4, 2008 at 8:59 PM, Carl Banks <pa************@gmail.comwrote:
>

You can write code to guard against this if you want:

class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
Carl Banks
--
http://mail.python.org/mailman/listinfo/python-list
<marco_scracthing_his_head>

Carl, I think I did not explained what I was asking the right way.

</marco_scracthing_his_head>

I'm not asking: "how can I do this sort of checks in Python": as I
stated before, if I want them, I will go for Java, or some other
language like that.

I understand that Python is a balance between different forces (like
any software object around the world) and I'm simply asking some
pointers to the discussion leading to this balance.

That's all.
--
Marco Bizzarri
http://notenotturne.blogspot.com/
http://iliveinpisa.blogspot.com/
Sep 5 '08 #11

P: n/a


Marco Bizzarri wrote:
I understand that Python is a balance between different forces (like
any software object around the world) and I'm simply asking some
pointers to the discussion leading to this balance.
The original decisions by Guido were nearly 20 years ago and other
discussions are scattered through the archive of this and the py-dev
list. But here is a pointer. Why go through the trouble of writing
functions that will set, get, and delete an attribute and the trouble of
calling those functions when you can use Python's existing syntax to do
it directly? More particularly, why would/should Guido force the
combersome indirection and time-penalty for writing, reading, and
execution on *every* Python programmer?

Of course, from my viewpoint, and for my usage,languages that do so
force are obnoxious.

tjr

Sep 5 '08 #12

P: n/a
Ivan Illarionov schrieb:
On 4 ֧ߧ, 21:49, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
>Ivan Illarionov a crit :
>>On 4 ֧ߧ, 22:59, Carl Banks <pavlovevide...@gmail.comwrote:
You can write code to guard against this if you want:
class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
'__slots__' is better:
For which definition of "better" ? __slots__ are a mean to optimize
memory usage, not to restrict dynamism. Being able to dynamically add
arbitrary attributes is actually a feature, not a bug, and uselessly
restricting users from doing so is not pythonic. IOW : don't do that.

Carl's example is restricting dynamism in the same way as __slots__.
I've just suggested a better implementation. It is not me who
suggested dynamism restriction as a way to guard against errors.
This is not correct. While Carl's Example looks similar, you actually
*can* create new attributes using

obj.__dict__['name'] = value

__slots__ OTOH prevents that because it does create instances *without*
an instance-dict.

This being said, I think we all agree that it's nothing to be desired.
Diez
Sep 5 '08 #13

P: n/a
On 5 ֧ߧ, 19:23, "Diez B. Roggisch" <de...@nospam.web.dewrote:
Ivan Illarionov schrieb:
On 4 ֧ߧ, 21:49, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.frwrote:
Ivan Illarionov a crit :
>On 4 ֧ߧ, 22:59, Carl Banks <pavlovevide...@gmail.comwrote:
You can write code to guard against this if you want:
class A:
legal = set(["x"])
def __setattr__(self,attr,val):
if attr not in self.legal:
raise AttributeError("A object has no attribute '%s'" %
attr)
self.__dict__[attr] = val
def __init__(self,x):
self.y = x
I suspect most people who go into Python doing something like this
soon abandon it when they see how rarely it actually catches anything.
'__slots__' is better:
For which definition of "better" ? __slots__ are a mean to optimize
memory usage, not to restrict dynamism. Being able to dynamically add
arbitrary attributes is actually a feature, not a bug, and uselessly
restricting users from doing so is not pythonic. IOW : don't do that.
Carl's example is restricting dynamism in the same way as __slots__.
I've just suggested a better implementation. It is not me who
suggested dynamism restriction as a way to guard against errors.

This is not correct. While Carl's Example looks similar, you actually
*can* create new attributes using

obj.__dict__['name'] = value

__slots__ OTOH prevents that because it does create instances *without*
an instance-dict.

This being said, I think we all agree that it's nothing to be desired.

Diez
+1 for unit tests as a way to guard against errors.

Bot sometimes __slots__ is exactly what I want (for other reasons) and
I like to avoid __getattr__ hacks in any situation.

Ivan
Sep 6 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.