class A:
a = 10
b = "Madhu"
def somemethod(self, arg1):
self.c = 20.22
d = "some local variable"
# do something
....
...
def somemethod2 (self, arg2):
self.c = "Changed the variable"
# do something 2
...
In such situations, where the Instance variables come into existence
only when they are used
it is very difficult to track the flow of code. Its obviously not
possible to remember what
instance variable was defined where, when reading some substantial
amount of code and where
it was manipulated for that matter. It becomes so very frustrating
even when reading a Class's
code with just 6-8 methods and not more than 100-150 lines of code.
I am interested in knowing if I am reading this kind of code in the
wrong way mostly because
of C++/Java hangover since most other languages follow the same
approach as them? If there
is a Pythonic way reading this code for better readability? What made
Python developers to
adopt this strange strategy keeping "Readibility Counts" in mind?
-- Python Rocks!
Madhusudan.C.S
Those are class variables, not instance variables. There is a distinct
difference. Instance variables, in contrast, are "declared" and
created in the body of the __init__ method.
>
> def somemethod(self, arg1):
> self.c = 20.22
> d = "some local variable"
> # do something
> ....
> ...
> def somemethod2 (self, arg2):
> self.c = "Changed the variable"
> # do something 2
> ...
>
> In such situations, where the Instance variables come into existence
> only when they are used
> it is very difficult to track the flow of code. Its obviously not
> possible to remember what
> instance variable was defined where, when reading some substantial
> amount of code and where
> it was manipulated for that matter. It becomes so very frustrating
> even when reading a Class's
> code with just 6-8 methods and not more than 100-150 lines of code.
That's bad coding style on the part of the code writer.
Conditionally-existing instance variables are *evil*.
Cheers,
Chris
--
Follow the path of the Iguana...
http://rebertia.com
In this case is the "c" attribute not "declared" in the __init__() method of A?
> I am interested in knowing if I am reading this kind of code in the
> wrong way mostly because
> of C++/Java hangover since most other languages follow the same
> approach as them? If there
> is a Pythonic way reading this code for better readability? What made
> Python developers to
> adopt this strange strategy keeping "Readibility Counts" in mind?
Not declaring instance variables is just poor form. IMHO Python code
should mostly be written like C++/Java. When you use "tricks" like the
above (dynamically adding attributes to a class) or getattr calls,
catching AttributeErrors, manipulating __dict__, decorators or
metaclasses you should really think twice whether you actually _need_
to use those tricks.
--
mvh Björn
Ok, let's clear up a couple misconceptions right now.
First: "Reabability counts" is a design principle of the language, not
a mandate that every Python programmer write readable code. If Django
project wants to write less readable code, they can. "Readability
counts" means that Python is designed to make it easy for the Django
project to write readable code if they choose.
Second: "Readability counts" is not the only factor that matters.
There are 19 Zen and sometimes they conflict with each other. Python
tries to balance all these concerns; it doesn't greedily maximize any
one of them. Some things might be a little less readable than they
could be, but oftentimes that's because other design considerations
were judged more important in that case.
Having cleared that up, let's consider your specific points.
> For example,
>
> class A:
> a = 10
> b = "Madhu"
>
> def somemethod(self, arg1):
> self.c = 20.22
> d = "some local variable"
> # do something
> ....
> ...
> def somemethod2 (self, arg2):
> self.c = "Changed the variable"
> # do something 2
> ...
>
> In such situations, where the Instance variables come into existence
> only when they are used
> it is very difficult to track the flow of code. Its obviously not
> possible to remember what
> instance variable was defined where, when reading some substantial
> amount of code
Impossible? You are seriously overstating things.
> and where
> it was manipulated for that matter.
This criticism is completely unfair. Instance variables have to be
manipulated somewhere, and unless your object is immutable, that is
going to happen outside of __init__. That's true in Java, C++, and
pretty much any other language.
> It becomes so very frustrating
> even when reading a Class's
> code with just 6-8 methods and not more than 100-150 lines of code.
>
> I am interested in knowing if I am reading this kind of code in the
> wrong way mostly because
> of C++/Java hangover since most other languages follow the same
> approach as them?
(Well, it is a lot safer in Python. In C++, if you try to use an
uninitialized variable, you'd get undefined behavior. Better to
initialize it to null and at least get a guaranteed segfault. In
Python if you try to use an uninitialized variable you'd get an
AttributeError.)
> If there
> is a Pythonic way reading this code for better readability? What made
> Python developers to
> adopt this strange strategy keeping "Readibility Counts" in mind?
I'm not going to argue that this doesn't hurt readability, because it
does (though not nearly as much as you claim). But there are other
considerations, and in this case the flexibility of defining
attributes outside __init__ is worth the potential decrease in
readability.
Here's a couple examples of where it's useful:
1. Sometimes classes are initialized without calling __init__, strange
but true. Look at the pickle module, for instance. It creates the
object without calling __init__ then sets all the instance variables
itself.
2. Some classes have factory classmethods that create the object by a
different means than calling __init__. (In fact, some classes have an
internal method that initializes variables, which __init__ and the
factories both call.)
3. Some objects, such as proxies, have uncertain sets of attributes.
Requiring such objects to predict all the variables they need inside
__init__ would limit their usability. Programmers would probably
resort to hack-like workarounds like Decorator Design Pattern.
4. It allows a simplification of the object system. Right now, all
attribute access is handled identically: at any point in time any
attribute may be set. If you wanted to limit attribute creation to
__init__, then it would mean objects have to have two phases (one,
during __init__, where you can create attributes; the other, where you
can only modify them). This would add significant complexity, and
"Simple is better than complex.
I'll also point out that even in C++/Java/etc. you have occasions
where an instance variable doesn't do anything until a something
triggers it. You can look to the constructor to see what it's
initialized to, but it isn't really initialized to anything useful
until some method call sets it to something useful. (Python makes it
explicit that the variable isn't in use until it is initialized, and
"Explicit is better than implicit".)
In the end, the answer to you question is simply, "Readibilty counts,
but other stuff matters too."
Carl Banks
The criticism is very valid. Some languages do support immutable
variables (e.g. "final" declarations in Java, "const" in C++, or
universal immutability in pure functional languages) and they do so
precisely for the purpose of taming the chaos of uncontrolled
mutation. It would be great if Python also supported immutability.
> I'm not going to argue that this doesn't hurt readability, because it
> does (though not nearly as much as you claim). But there are other
> considerations, and in this case the flexibility of defining
> attributes outside __init__ is worth the potential decrease in
> readability.
There are cases where this is useful but they're not terribly common.
I think it would be an improvement if creating new object attributes
was by default not allowed outside the __init__ method. In the cases
where you really do want to create new attributes elsewhere, you'd
have to explicitly enable this at instance creation time, for example
by inheriting from a special superclass:
class Foo (DynamicAttributes, object): pass
> 4. It allows a simplification of the object system. Right now, all
> attribute access is handled identically: at any point in time any
> attribute may be set. If you wanted to limit attribute creation to
> __init__, then it would mean objects have to have two phases (one,
> during __init__, where you can create attributes; the other, where you
> can only modify them). This would add significant complexity, and
> "Simple is better than complex.
On the other hand, correct is better than buggy.
Do you mean conditionally-useful instance variables evil, or that
conditionally-useful variables are ok but it's evil for them to
conditionally-exist?
The former I don't agree with at all.
If it's the latter, I believe there is something to be said for
variables that exist when they are needed and don't when they're not.
However, I acknowledge that listing all the variables you intend to
use in __init__ is highly comforting, even if it does belie their
current uselessness.
Carl Banks
I don't think what you said (which is fine) makes his criticism valid,
unless you also suggest that all objects should be immutable.
If any objects are mutable, you have to be prepared for objects to
mutated outside the initializer.
I guess it could be a valid criticism of Django's progamming style
("They mutate stuff haphazardly everywhere!!~") but that's not the
Python langauge's problem.
> > 4. It allows a simplification of the object system. Right now, all
> > attribute access is handled identically: at any point in time any
> > attribute may be set. If you wanted to limit attribute creation to
> > __init__, then it would mean objects have to have two phases (one,
> > during __init__, where you can create attributes; the other, where you
> > can only modify them). This would add significant complexity, and
> > "Simple is better than complex.
>
> On the other hand, correct is better than buggy.
What bugginess do you speak of? Adding a variable outside __init__ is
questionable style, not a bug. I don't think it's a significant
source of bugs, either. And I definitely don't think the language
should add a layer of complexity (and I think you're underestimating
the complexity of making the whole object system two-phase) just to
prevent a minor style issue.
pychecker is the appropriate tool to diagnose this issue.
Carl Banks
It would be enough to have a way to make specific objects and instance
attributes immutable.
> If any objects are mutable, you have to be prepared for objects to
> mutated outside the initializer.
Sure, but why have mutable objects all over the place? And, why
always have attributes visible at all, outside the class definition?
The approach in C++ and Java is to have public and private instance
variables, where the private ones are visible only in the class methods.
The latter. I never even used the word "useful", so I have no idea
where you got that from.
To reiterate, variables which might only exist under certain
conditions are evil, IMHO.
This is not to say they are not useful in certain specific cases, just
that in general there are better ways to design/structure programs to
avoid them.
Regarding the second question, Python adheres to the principle that
"We're all consenting adults here" and so does not provide complete
encapsulation like more B&D languages. This is handy sometimes as it
allows one to break through the encapsulation when necessary and
fiddle with the internals. This is not to say that breaking
encapsulation willy-nilly is advised, but it does allow for some neat
hackery every now and again.
[Dynamically adding and removing instance attributes...]
> Here's a couple examples of where it's useful:
>
> 1. Sometimes classes are initialized without calling __init__, [...]
> 2. Some classes have factory classmethods [...]
> 3. Some objects, such as proxies, have uncertain sets of attributes. [...]
> 4. It allows a simplification of the object system. [...]
All good points. I'd like to add a fifth: it can provide a handy hook
for one module to hang data off of another module's objects. This sort
of thing isn't very nice, but it's sometimes the best way.
(Other approaches include using wrappers, which might be very invasive
if opaque, or don't actually solve the name-collision problem if
transparent; or maintaining a dictionary, which involves messing about
with weak pointers if you want to keep it from filling with cruft.)
> In the end, the answer to you question is simply, "Readibilty counts,
> but other stuff matters too."
Amen.
-- [mdw]
> In such situations, where the Instance variables come into existence
> only when they are used it is very difficult to track the flow of code.
As the saying goes, "It's possible to write Fortran in any language".
My personal habit is to "declare" all instance variables in the __init__()
method of every class. If there's no better value, I set them to None.
This isn't strictly required, but I think it makes it easier for somebody
reading the code to understand the class.
I'm not a big fan of dogmatic rules, other than the rule that says you
should make your code as easy for somebody else to understand as possible.
I was just asking for clarification of your rationale, of which I
imagined two possibilities ("conditional-usefulness is bad", or
"declaring attributes outside of __init__" is bad). However...
> To reiterate, variables which might only exist under certain
> conditions are evil, IMHO.
> This is not to say they are not useful in certain specific cases, just
> that in general there are better ways to design/structure programs to
> avoid them.
...the way you phrase this suggests to me that conditional-usefulness
*is* what you are really concerned with. Let me give you an example:
class A:
def __init__(self):
pass
def something(self):
self._conditionally_existent_variable = 1
ISTM that I don't need any restructuring at all to avoid conditional
existence; all I'd have to do is add
self._conditionally_existent_variable = None
to __init__. If you think I need to restructure this code, than you
evidently care about something more than just conditional existence.
If so, what is it that's so evil about conditionally-existent
variables? (I'll leave the question open-ended this time.)
Carl Banks
Roy i totally agree and as i read down this thread i was thinking i
might get to spit that out first but you beat me -- Darn!
PS: your explanation is also much more eloquent than mine would have
been :)
I have found they make the code more confusing and bug prone.
It's better to define and document all the instance variables
in one place, in most cases.
Enough for what, to make the guy's criticism valid? No it wouldn't.
Or are you just ignoring the OP altogether and complaining about what
bothers you?
For my part I am concerned with answering the OP's issues here, not
yours.
> > If any objects are mutable, you have to be prepared for objects to
> > mutated outside the initializer.
>
> Sure, but why have mutable objects all over the place? And, why
> always have attributes visible at all, outside the class definition?
> The approach in C++ and Java is to have public and private instance
> variables, where the private ones are visible only in the class methods.
The OP wasn't complaining about the fact that objects aren't
immutable, as far as I can tell, nor about having public and private
variables, so I can't agree Python's lack of these has anything to do
with the OP's concerns.
Carl Banks
That means all I have to do is add a stopgap value in __init__. I'm
asking Chris why that is evidently not enough, and that I'd have to
structure/design my code to avoid it.
Carl Banks
> This is not to say that breaking encapsulation willy-nilly is advised,
> but it does allow for some neat hackery every now and again.
I'm all for neat hackery, except when used in code that I need to read and
understand.
No, this is exactly the sort of restructuring I was referring to; and
nothing more. Making that one-line change would be sufficient for me.
Perhaps "restructuring" was a poor choice of words...
You cannot do that, but you can establish a fixed set of attributes by
defining
the __slot__ class variable.
Ciao
-----
FB
That is not what __slot__ is for.
Right. And tuples are not immutable lists (ducking and covering).
Really? It seems to work:
>>> class A(object):
... __slots__ = ('a', 'b')
... def __init__(self): self.not_allowed = 1
...
>>> a = A()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 3, in __init__
AttributeError: 'A' object has no attribute 'not_allowed'
>>>
Ciao
-----
FB
> On 12 Gen, 14:45, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
>> bieff...@gmail.com writes:
>> > > class Foo (DynamicAttributes, object): pass
>>
>> > You cannot do that, but you can establish a fixed set of attributes
>> > by defining the __slot__ class variable.
>>
>> That is not what __slot__ is for.
>
>
> Really? It seems to work:
It works but it is not what `__slot__` was invented for. Some call it a
misuse of that feature if you use it to prevent adding attributes
dynamically. And it has some drawbacks when you inherit from such
classes.
Ciao,
Marc 'BlackJack' Rintsch
Why on earth are you using Python if you don't like the way it work ???
Why on earth keep releasing new versions of Python if the old ones are
already perfect?
Why on earth are you busting into someone's thread just because you
don't like what they have to say ???
That's a fallacious argument. Nobody is arguing that any specific version
of Python is perfect, but clearly many people do like the general design
choices of the language, that is, the way it works.
*If* you don't like the way it works, and you have a choice in the
matter, perhaps you should find another language that works more the way
you would prefer.
On the other hand... Bruno's question is unfair. It is perfectly
reasonable to (hypothetically) consider Python to be the best *existing*
language while still wanting it to be improved (for some definition of
improvement). Just because somebody has criticisms of Python, or a wish-
list of features, doesn't mean they hate the language.
--
Steven
WOW Steven, i am very impressed. That's the first thing you have said
in a very long time that i totally agree with! Keep this up and i may
put you back on my Python Brethren list :)
We are in an era for programming languages sort of like the Windows 95
era was for operating systems, where everything is broken but some of
the fixes are beginning to come into view. So there is no language
that currently really works the right way, but some of them including
Python are (one hopes) moving in good directions. Maybe I can help
that process along by posting, maybe not.
Paul,
Python is the best hope for readable, maintainable very high-level
coding. Python forged the path and showed all other languages for what
they truly are; archaic, redundant, pieces of complete rubbish! In my
mind only 2 languages stand out in the very high level category;
Python and Ruby. Ruby only exists in this world because of the things
it took from Python. Nobody would touch Ruby without it's Pythonisms.
Python wins hands down, WHY? you ask. Well i could list a thousand
reasons why but i will only cover a few.
1.) read-ability
2.) learn-ability
3.) maintain-ability
4.) perfect choice of keywords
5.) no end statement, braces, or lisps!
6.) no forced capitalizations
7.) modules are the actual script name
8.) introspection
9.) class, and class inheritance is beautiful
8.) true procedural support(no instance vars needed)
10.) loads of quality documentation!
11.) IDLE
12.) Guido (the genius that made all this happen!)
I could keep going for days and days. Python is hands down the best
thing that ever happened to the world of programming. Sure it could
use a few improvements, nothing and nobody is perfect. But can any
language stand toe to toe with Python? HELL NO!
> In article
> <34c95e04-5b3f-44bc...@p36g2000prp.googlegroups.com>,
> "Madhusudan.C.S" <madhus...@gmail.com> wrote:
>
> > In such situations, where the Instance variables come into existence
> > only when they are used it is very difficult to track the flow of code.
>
> As the saying goes, "It's possible to write Fortran in any language".
>
> My personal habit is to "declare" all instance variables in the __init__()
> method of every class. If there's no better value, I set them to None.
> This isn't strictly required, but I think it makes it easier for somebody
> reading the code to understand the class.
I agree with you. I do exactly this. It prevents a lot of problems by
giving one place to look for class variables and comments on them.
Setting to None is good, too, since many times if I use one before
setting a value I'll get an exception or really bad results that I can
easily trace to the unset variable.
> I'm not a big fan of dogmatic rules, other than the rule that says you
> should make your code as easy for somebody else to understand as possible.
Right.
--
-- Lou Pecora
I confess to not knowing much about Ruby. It looks sort of Perl-ish
to me, and I always hear it is slower than Python, which is already
too slow.
> Python wins hands down, WHY? you ask. Well i could list a thousand
> reasons why but i will only cover a few.
>
> 1.) read-ability
> 2.) ...
> I could keep going for days and days. Python is hands down the best
> thing that ever happened to the world of programming. Sure it could
> use a few improvements, nothing and nobody is perfect. But can any
> language stand toe to toe with Python? HELL NO!
Those things on your list are all nice, but I think Python has
considerable room for improvement in several areas:
1) Parallelism. Commodity desktop computers now have 8 effective cpu
cores or maybe even 16 soon (Mac Pro, Intel Core i7) but Python still
has the evil GIL that forces all threads to run on one core. Java,
Erlang, and Haskell (GHC) all beat Python in this area. By the time
Python 4 comes out, we will probably all be using PC's with 32 or more
cores, so the current limitations will be intolerable. Even today,
since no one doing anything serious uses single core machines any
more, the GIL is a huge pain in the neck which the multiprocessing
module helps only slightly. (While we are at it, lightweight threads
like Erlang's or GHC's would be very useful.)
2) Native-code compilation. Per the Alioth shootouts, Python is much
slower (even on single cores) than Java, Haskell, ML, or even Scheme.
PyPy is addressing this but it will be a while before it replaces
CPython.
3) Data encapsulation, the subject of most of this thread.
4) Static analysis. It would be great if there were a much more
powerful Pylint that could do ML-like type inference among other
things. You could still program in a dynamic, heterogeneous style if
you wanted to, but Pylint would complain about it unless you supplied
some annotations to tell it where the dynamism was and how to separate
it from the rest of the program. This is consistent with Python's
"consenting adults" principle: if consenting adults want to
participate in a BDSM scene, they should be allowed to. There would
probably have to be some new language features to assist in writing
typefully. Python 3.0 has some gestures in this direction but they
are not yet fully formed.
I believe that the PyPy project is developing the above areas in ways
CPython really could not. While we are now committed to Python 3.0
being a CPython revision that makes some minor (and in my view
somewhat gratuitous) changes to the 2.x series, I hope that Python 4.0
will be based on PyPy and have more substantial differences.
Thanks for that nice appraisal. I agree completely.
I've suggested before here (as have others) that some sort of basic
data encapsulation would be nice, but many Python users don't seem to
want anything to do with it.
Also, static analysis would be very desirable for my purposes. I would
be more than happy to declare types if someone else would write an
advanced static analyser that could make use of the type information
and formally check the code for correctness. That has been done for
other languages such as Java and Ada, and it can be very useful for
safety-critical and mission-critical software. (I am currently
developing a research prototype of safety-critical software.)
I started looking at Scala a while back. It is has many nice features.
It seamlessly combines object orientation with advanced functional
programming. It is statically typed, but the types often do not need
to be explicitly declared. It is fully "compatible" with Java, but
(like Python) it is much less verbose and more elegant, typically
requiring less (in some cases, much less) than half the lines of code
for a given task.
But I am reluctant to use Scala for several reasons. For example, it
doesn't have "continue" and "break." The Scala folks claim they are
unnecessary, but they are sure handy sometimes. Maybe my style is bad,
but I use continue and break a lot, particularly continue. Getting by
without them could be hard. The other thing is that Scala has no
default arguments and no argument passing by keyword. Those are a
couple of my favorite Python features. So I'm basically screwed.
There exists in the world of very-high-level languages only two big
players -- Python and Ruby. The only reason Ruby even exist is because
of what Mats stole from Python. Ruby is a corrupting and hideous
language, that will ruin all future "scripters" with it's abominations
of coding styles. Ruby is basically Perl's "Mini-Me". A small but
deadly form of viral infection that will plague us all for many years
to come with unreadable, unmaintainable code! I lament every day the
creation of Ruby language. Ruby took the only good things it possess
from Python.
A little History Lesson:
Python came into being around 1991 by a computer science genius named
"Guido van Rossum". This man is truly a man before his time. Python
revolutionized the world of programming and exposed the other
languages for what they are. Archaic, and redundant pieces of
petrified dino dookie. Python promotes good coding styles by
indentation(ruby stole that) Python's syntax is clear, and choice of
keywords is perfect(ruby stole some of that too). Python allows for
true OOP and true procedural(ruby tried to steal that but failed
miserably)
I like to think of Python as simplistic programming elegance. No other
high level language can compete with Python, so what did Ruby DEV do?
They stole from Python, thats what! And they did not bother to mention
this little tidbit of info to new recruits on their website!Tthey act
as if Ruby were here first. And pay no respect to the path Python
forged. Ruby owes it's very existence to Python!
I will never get over the use of "end". Why on GODS green earth would
you use indentation AND the "end" statement? That's completely
redundant. That would be the same as using two periods at the end of a
sentence.. Complete monkey logic!
Python is better, but we must stay alert and not fall asleep at the
wheel. I think Python DEV has good intention, but they do not realize
the battle that lay ahead. We must fight to get Python in every API we
can. We must stay on our toes and not let Ruby one-up us! I do not
want to see Python go down the evolutionary toilet! Lets send Ruby to
programming HELL!
Heh, I have to admire your enthusiasm. That testimonial is truly
suitable for framing ;-)
What can one do to get *off* it? ;-)
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
So does using a butt-plug to seal a bottle of wine, but that's still not
what it's for.
regards
Steve
> 2) Native-code compilation. Per the Alioth shootouts, Python is much
> slower (even on single cores) than Java, Haskell, ML, or even Scheme.
> PyPy is addressing this but it will be a while before it replaces
> CPython.
>
Speed, of course, isn't everything. But it would be nice to accommodate
those problem classes where it *is* significant.
> 3) Data encapsulation, the subject of most of this thread.
>
There's always more to do there, though I fell the thread started out
based on a misapprehension.
> 4) Static analysis. It would be great if there were a much more
> powerful Pylint that could do ML-like type inference among other
> things. You could still program in a dynamic, heterogeneous style if
> you wanted to, but Pylint would complain about it unless you supplied
> some annotations to tell it where the dynamism was and how to separate
> it from the rest of the program. This is consistent with Python's
> "consenting adults" principle: if consenting adults want to
> participate in a BDSM scene, they should be allowed to. There would
> probably have to be some new language features to assist in writing
> typefully. Python 3.0 has some gestures in this direction but they
> are not yet fully formed.
>
That part of Python 3'sw design is, of course, totally intentional. I
believe Guido is on record as saying that he hopes the uses for the
annotation feature can be concretized (is that a word) down the line
when good use cases have emerged. And I believe they will (as you
suggest to be desirable) always be optional - almost like a pragma in
other languages.
> I believe that the PyPy project is developing the above areas in ways
> CPython really could not. While we are now committed to Python 3.0
> being a CPython revision that makes some minor (and in my view
> somewhat gratuitous) changes to the 2.x series, I hope that Python 4.0
> will be based on PyPy and have more substantial differences.
I have to confess that I occasionally find some of your posts a bit
pedantic and obscurantist. Just the same I appreciate your continued
presence on the list, because no matter how unreasonable I feel what you
says to be, when I examine it I always find your opinions well expressed
and well thought-out.
Sometimes I just want to shout "be quiet, Python is just fine the way it
is", but alas your objections are usually too sensible to be dismissed
in that way. In the long term I feel it has to be good for Python that
it has such conscientious critics.
Ultimately it may well be that some other project than CPython
represents the way forward for the language. I don't think that day has
arrived yet, but that doesn't mean we should exclude the possibility out
of hand.
> r wrote: (about another Steven)
> > WOW Steven, i am very impressed. That's the first thing you have said
> > in a very long time that i totally agree with! Keep this up and i may
> > put you back on my Python Brethren list :)
>
> What can one do to get *off* it? ;-)
eeh by gum lad - there's nowt for it -
tis direct result of heavy infestation
of people on planet!
- Hendrik
Thanks for making my point clear.
> *If* you don't like the way it works, and you have a choice in the
> matter, perhaps you should find another language that works more the way
> you would prefer.
>
> On the other hand... Bruno's question is unfair. It is perfectly
> reasonable to (hypothetically) consider Python to be the best *existing*
> language while still wanting it to be improved (for some definition of
> improvement).
And that's the problem : what Paul suggests are not "improvements" but
radical design changes. The resulting language - whatever it may be
worth, I'm not making any judgement call here - would not be Python
anymore.
> Just because somebody has criticisms of Python, or a wish-
> list of features, doesn't mean they hate the language.
There's probably a whole range of nuances between "not liking" and
"hating". And Paul is of course perfectly right to think that a language
having this and that features from Python, but not this other one, would
be a "better" language (at least according to it's own definition of
"better"). Where I totally disagree is that it would make *Python* better.
Also, my question was not that "unfair" (even if a bit provocative). I
really wonder why peoples that seems to dislike one of the central
features of Python - it's dynamism - still use it (assuming of course
they are free to choose another language). And FWIW, I at least had a
partial answer on this.
I think the issue here is the distinction between hacking and software
engineering. I may be misusing the term "hacking," but I do not mean
it in a pejoritive sense. I just mean getting things done fast without
a lot of concern for safety, security, and long-term maintainability
and scalability. I'm not a computer scientist, but it seems to me that
Python is great for hacking and good for software engineering, but it
is not ideal for software engineering.
What Paul is suggesting, I think, is that Python should move in the
direction of software engineering. Whether that can be done without
compromising its hacking versatility is certainly a valid question,
but if it can be done, then why not do it?
Certainly one basic principle of software engineering is data
encapsulation. Tacking new attributes onto class instances all over
the place may be convenient and useful in many cases, but it is not
consistent with good software engineering. If the programmer could
somehow disallow it in certain classes, that could be useful,
providing that those who wish to continue doing it would be free to do
so. If class attributes could somehow be declared private, that would
be useful too. Optional explicit type declarations could also be
useful -- and I believe Python does have that now, so no need to argue
about that.
Why do I continue to use Python when I have so many "complaints" about
it? As everyone here knows, it has many good qualities. My work falls
somewhere in the middle between "hacking" and software engineering. I
am developing a research prototype of a safety-critical system. A
research prototype is not safety-critical itself, and it needs to be
flexible enough to try new ideas quickly, but it also needs to serve
as a model for a well-engineered system. Is Python the right choice? I
think so, but I don't know for sure.
Eh? I think of them as moderate and incremental improvements, in a
direction that Python is already moving in. Radical would be
something like a full-scale static type system.
> I really wonder why peoples that seems to dislike one of the central
> features of Python - it's dynamism - still use it (assuming of
> course they are free to choose another language).
I certainly don't think dynamism is central to Python. In what I see
as well-developed Python programming style, it's something that is
only rarely used in any important way. I'd spend much less time
debugging if I got compiler warnings whenever I used dynamism without
a suitable annotation. The 1% of the time where I really want to use
dynamism I don't see any problem with putting in an appropriate
decorator, superclass, or whatever.
I've seen no evidence that any Python project is moving even remotely
toward data encapsulation. That would be a drastic change. Even if
it were only a minor change in the implementation (and it would not
be), it would be a major stroke in the Python community. It would
basically cause a wholescale power shift from the user to the
implementor. As a user it'd be like the difference between living in
a free democracy and a fascist dictatorship.
> Radical would be
> something like a full-scale static type system.
>
> > I really wonder why peoples that seems to dislike one of the central
> > features of Python - it's dynamism - still use it (assuming of
> > course they are free to choose another language).
>
> I certainly don't think dynamism is central to Python. In what I see
> as well-developed Python programming style, it's something that is
> only rarely used in any important way.
You're in the minority, then.
> I'd spend much less time
> debugging if I got compiler warnings whenever I used dynamism without
> a suitable annotation. The 1% of the time where I really want to use
> dynamism I don't see any problem with putting in an appropriate
> decorator, superclass, or whatever.
Well, I guess you are the sacrifical lamb so that everyone else can
take advantage of the dynamicism.
Carl Banks
> I've seen no evidence that any Python project is moving even remotely
> toward data encapsulation. That would be a drastic change. Even if
> it were only a minor change in the implementation (and it would not
> be), it would be a major stroke in the Python community. It would
> basically cause a wholescale power shift from the user to the
> implementor. As a user it'd be like the difference between living in
> a free democracy and a fascist dictatorship.
I just googled "object oriented principles." The first site that came
up lists four princicples:
- Encapsulation
- Abstraction
- Inheritance
- Polymorphism
The Wikipedia entry for "object-oriented programming" also lists
encapsulation as a "fundamental concept."
The first line on the python.org site says:
"Python is a dynamic object-oriented programming language that can be
used for many kinds of software development."
How can that possibly be true if you see "no evidence that any Python
project is moving even remotely toward data encapsulation"?
Semantics aside, I fail to understand your hostility toward a
fundamental concept of object-oriented programming. The difference
between a free democracy and a "fascist dictatorship"? Give me a
break!
The Wikipedia entry for "encapsulation" defines it as "the grouping
together of data and functionality".
That sounds like Python classes & modules to me.
Here's the definition on the Wikipedia page for object oriented
programming (and it does *not* sound like Python classes):
Encapsulation conceals the functional details of a class from objects
that send messages to it. ... Encapsulation is achieved by specifying
which classes may use the members of an object. The result is that
each object exposes to any class a certain interface — those members
accessible to that class. The reason for encapsulation is to prevent
clients of an interface from depending on those parts of the
implementation that are likely to change in future, thereby allowing
those changes to be made more easily, that is, without changes to
clients. For example, an interface can ensure that puppies can only be
added to an object of the class Dog by code in that class. Members are
often specified as public, protected or private, determining whether
they are available to all classes, sub-classes or only the defining
class. Some languages go further: Java uses the default access
modifier to restrict access also to classes in the same package, C#
and VB.NET reserve some members to classes in the same assembly using
keywords internal (C#) or Friend (VB.NET), and Eiffel and C++ allow
one to specify which classes may access any member.
You do realize this is a model and not
strictly a requirement. Quite a few things
in Python are done merely by convention.
Don't get caught up.
--JamesMills
But, if something is done by convention, then departing from the
convention is by definition unconventional. If you do something
unconventional in a program, it could be on purpose for a reason, or
it could be by accident indicating a bug.
I don't understand why some folks spew such violent rhetoric against
the idea of augmenting Python with features to alert you automatically
when you depart from the convention, so that you can check that the
departure is actually what you wanted. A lot of the time, I find, the
departures are accidental and automated checks would save me
considerable debugging.
Amen to that! Finally someone with some sense and
his/her head screwed on properly! :)
Kudos to your thoughtful post :)
cheers
James
public = no leading underscore
private = one leading underscore
protected = two leading underscores
Python uses encapsulation by convention rather than by enforcement.
> they are available to all classes, sub-classes or only the defining
> class. Some languages go further: Java uses the default access
> modifier to restrict access also to classes in the same package, C#
> and VB.NET reserve some members to classes in the same assembly using
> keywords internal (C#) or Friend (VB.NET), and Eiffel and C++ allow
> one to specify which classes may access any member.
As mentioned previously this is not encapsulation, but
access control. But yes correct, this is how we conventionally
define access control over members of an object. It's up to the
programmer correctly adhere to the interface(s).
--JamesMills
Yes, but the fact that you can approximate OO programming in a
particular language does not make that language object oriented. You
can approximate OO programming in C, but that does not mean that C is
an OO language.
So I can claim that Python is not strictly object oriented until it
gets encapsulation (in the sense of data hiding). That is simply a
fact, and no amount of pleading or obfuscation will change it.
Should Python get true encapsulation? I don't know. Maybe
encapsulation cannot be added without excessive overhead or without
compromising other more important aspects and features of the
language. But I do know that not having encapsulation is a limitation
to the use of Python for good software engineering. I may be in the
minority in the Python "community" on this one, but I am apparently in
the majority in the OO programming "community."
> But, if something is done by convention, then departing from the
> convention is by definition unconventional. If you do something
> unconventional in a program, it could be on purpose for a reason, or
> it could be by accident indicating a bug.
I wouldn't violently object to having some means of policing class
or module privacy, but it does have consequences. When it's a
convention, you can break it; when it isn't, you can't, even if
you do have good reason. Add that to the obviousness of the
"leading underscore => private" convention, and I just don't see
a burning need for it, that's all.
--
Rhodri James *-* Wildebeeste Herder to the Masses
Very well said Terry!
I like that python does not force me to do "everything" but does force
things like parenthesis in a function/method call whether or not an
argument is required/expected. This makes for very readable code.
Visual parsing a Python file is very easy on the eyes due to this fact
-- Thanks Guido! We do not need to add three new keywords when there
is an accepted Pythonic way to handle public/private/protected
Wrong. Not having strict and enforced access control 9_NOT_ encapsulation)
(Please stop confusing the two) is not a strict requirements of the OO model.
Remember that it is a model and not a strict set of requirements that
programming
languages must implement.
In fact, Python borrows features from the Functional Paradigm. Does this
make it a Functional Language ? No. Why ? Because one of the clear
requirements of the Functional Paradigm is that functions cannot have
side affects.
> So I can claim that Python is not strictly object oriented until it
> gets encapsulation (in the sense of data hiding). That is simply a
> fact, and no amount of pleading or obfuscation will change it.
In fact this is true, C can be seen as an programming language
that has features of the OO model.
I think one of the things you guys are missing out
here is that there are really only two Paradigms
or Machines. Functional and Imperative. And guess
what ? As it turns out we can implement functional
machines that run on top of imperative ones!
> Should Python get true encapsulation? I don't know. Maybe
> encapsulation cannot be added without excessive overhead or without
> compromising other more important aspects and features of the
> language. But I do know that not having encapsulation is a limitation
> to the use of Python for good software engineering. I may be in the
> minority in the Python "community" on this one, but I am apparently in
> the majority in the OO programming "community."
Again, stop confusing terminology.
Should Python get strict and enforce access control
of object members ? No. Why ? I can think of several
reasons.
Give me one use-case where you strictly require
that members of an object be private and their
access enforced as such ?
cheers
James
Bare in mind also, that enfocing access control / policing as you
called it has a performance hit as the machine (the Python vm)
has to perform checks each time members of an object are accessed.
I can think of no reason to want to do this at runtime hwatosever
and I've been developing in Python for quite some years now.
cheers
James
Agreed. Furthermore there very few cases where you need
to distinguish between whether an object's attribute is public
or private or even protected.
Consider the following two pieces of code and tell me
which is more Pythonic:
class A(object):
def __init__(self):
self.x = None
def setX(self, v):
self.x = v
def getX(self):
return self.x
----------------------------------------
class A(object):
def __init__(self):
self.x = None
I'll give you a hint ... It's the simpler one :)
cheers
James
Is this seriously your argument? Python must be moving towards data
encapsulation because there is a line in Python.org that, if you
blindly accept the Wikipedia definition as truth, indirectly implies
that it is?
Are you *seriously* arguing this?
The argument is too ridiculous to deserve a refutation, so I'll just
point out two things:
1. Wise people don't believe everything that is written on Wikipedia.
2. The person who wrote that line in Python.org is a wise person.
> Semantics aside, I fail to understand your hostility toward a
> fundamental concept of object-oriented programming. The difference
> between a free democracy and a "fascist dictatorship"? Give me a
> break!
You know what? Computer science buzzwords mean jack squat to me. I
don't give a horse's tail whether some people label it a fundamental
concept of object-oriented programming or not. I think it's a bad
thing. And it's a bad thing for exactly the reason I said: it gives
the library implementor the power to dictate to the user how they can
and can't use the library. The cultural impact that would have on the
community is far worse, IMHO, than any short-sighted benefits like
being able to catch an accidental usage of an internal variable.
Trust would be replaced by mistrust, and programming in Python would
go from a pleasant experience to constant antagonism.
No thanks. "Software engineering" be damned. Python is better off
the way it is.
Carl Banks
And I'll give you a perfect example:
XML-DOM versus ElementTree
XML-DOM is the sort of standard that is borne of a culture that values
encapsulation, strict type safety, and so on. It's the way it is
because designers were allowed to distrust the user, and the culture
said that it was good to distrust the user. Consequently, the
interface is a pain to use, with all kinds of boilerplate and iterator
types and such.
ElementTree was borne out of an environment where implementors are
forced to trust the user. As a consequence it was free to create an
interface that was natural and straightforward and pleasant to use,
without having to be guarded.
Carl Banks
I agree, the second the Python interpretor say's NO! you cant do that
or i will wrap your knuckles! is the day i leave Python forever. I
hear C programmers complain all the time about Python saying; "Well, I
like in "C" that variable types must be declared because this keeps me
from making mistakes later" -- hog wash! Just learn to think in a
dynamic way and you will never have any problems. If you need a hand
holding language i guess Python is not for you. And don't forget, you
can learn a lot from your mistakes.
They are so brainwashed by this mumbo-jumbo, i see them do this all
the time...
int_count = 0
float_cost = 1.25
str_name = "Bob"
They can't think in a dynamic way because momma "C" has done it for
them for too long. "Eat your Peas and carrots now little C coder" :D
Agreed.
> You know what? Computer science buzzwords mean jack squat to me. I
> don't give a horse's tail whether some people label it a fundamental
> concept of object-oriented programming or not. I think it's a bad
> thing. And it's a bad thing for exactly the reason I said: it gives
> the library implementor the power to dictate to the user how they can
> and can't use the library. The cultural impact that would have on the
> community is far worse, IMHO, than any short-sighted benefits like
> being able to catch an accidental usage of an internal variable.
> Trust would be replaced by mistrust, and programming in Python would
> go from a pleasant experience to constant antagonism.
+1
> No thanks. "Software engineering" be damned. Python is better off
> the way it is.
Python ihmo is one of the best engineered programming languages
and platform I have ever had the pleasure of working with
and continue to! :)
--JamesMills
> I can claim that Python is not strictly object oriented until it
> gets encapsulation (in the sense of data hiding). That is simply a
> fact, and no amount of pleading or obfuscation will change it.
I have no idea if Python is strictly anything. What I do know is that it's
a useful tool. I'll take useful over OOO (Object Oriented Orthodoxy) any
day.
People get all worked up over OO as if it were some kind of religion. If I
want religion, I'll go to shul. What I want from a programming language is
a tool that lets me get my work done. If I transgress against some sacred
tenet of OO religion, it is, as Rev. Dupas would say, all right.
Earlier in this thread, somebody (name elided to avoid me getting pegged
for a indulging in a spelling flame):
> Bare in mind also, that enfocing access control / policing as you
> called it has a performance hit as the machine (the Python vm)
> has to perform checks each time members of an object are accessed.
All I can say to that is, "He who bares his mind, soon gets to the naked
truth".
Did you read what I wrote? If so, you apparently didn't understand it.
> The argument is too ridiculous to deserve a refutation, so I'll just
> point out two things:
>
> 1. Wise people don't believe everything that is written on Wikipedia.
Nice try at diverting attention. The issue is not Wikipedia. As far as
I know, the definition of OOP given on Wikipedia is not controversial
-- at least not anywhere but here.
> 2. The person who wrote that line in Python.org is a wise person.
Oh, isn't that wonderful. Wow, I sure wish I was wise like that
person!
> > Semantics aside, I fail to understand your hostility toward a
> > fundamental concept of object-oriented programming. The difference
> > between a free democracy and a "fascist dictatorship"? Give me a
> > break!
>
> You know what? Computer science buzzwords mean jack squat to me. I
> don't give a horse's tail whether some people label it a fundamental
> concept of object-oriented programming or not. I think it's a bad
> thing. And it's a bad thing for exactly the reason I said: it gives
> the library implementor the power to dictate to the user how they can
> and can't use the library. The cultural impact that would have on the
> community is far worse, IMHO, than any short-sighted benefits like
> being able to catch an accidental usage of an internal variable.
> Trust would be replaced by mistrust, and programming in Python would
> go from a pleasant experience to constant antagonism.
>
> No thanks. "Software engineering" be damned. Python is better off
> the way it is.
Now that's just classic. "We have Python and we don't need no stinkin'
software engineering." Well, you may not need it in your line of work,
but I need it in mine. In my line of work, Python is a tool, not a
religious faith.
I swear, before god, this is the exact code he showed me. If you don't
believe me i will post a link to the thread.
// Warning ugly C code ahead!
if( is_opt_data() < sizeof( long double ) ) { // test for insufficient
data
return TRUE; // indicate buffer empty
} // end test for insufficient data
if( is_circ() ) { // test for circular buffer
if( i < o ) { // test for data area divided
if( ( l - o ) > sizeof( long double ) ) { // test for data
contiguous
*t = ( ( long double * ) f )[ o ]; // return data
o += sizeof( long double ); // adjust out
if( o >= l ) { // test for out wrap around
o = 0; // wrap out around limit
} // end test for out wrap around
} else { // data not contiguous in buffer
return load( ( char * ) t, sizeof( long double ) ); // return
data
} // end test for data contiguous
} else { // data are not divided
*t = ( ( float * ) f )[ o ]; // return data
o += sizeof( long double ); // adjust out
if( o >= l ) { // test for out reached limit
o = 0; // wrap out around
} // end test for out reached limit
} // end test for data area divided
} else { // block buffer
*t = ( ( long double * ) f )[ o ]; // return data
o += sizeof( long double ); // adjust data pointer
} // end test for circular buffer
if i where to write the same code in a 'Python style" it would look
like below. And personally i would never use that many comments in my
code. I normally in a situation as this one would only comment each
major conditional code block, and only if it contains code that is not
completely obvious. Commenting is important, but it *can* be over
done.
#-- Python Style --#
if is_opt_data() < sizeof(long double):
return TRUE
if is_circ():
if i < o: #test for data area divided
if (l-o) > sizeof(long double): #test for data contiguous
*t = ( ( long double * ) f )[ o ]
o += sizeof( long double )
if o >= l:
o = 0
else: #data not contiguous in buffer
return load((char*) t, sizeof(long double))
else: #data are not divided
*t = ((float*) f)[ o ]
o += sizeof(long double)
if o >= l: #test for out reached limit
o = 0
else: #block buffer
*t = ((long double*) f)[ o ]
o += sizeof(long double)
WOW!, without all the braces, and over commenting, i can actually
read this code now! Of course it would not run in C or Python but the
point here is readability. Python forged the path for all 21st century
languages. Get on board, or get on with your self.extinction() -- Your
Choice!
I think you are the one who is confused. Part of the problem here is
that the term "encapsulation" has at least two widely used meanings
(in the context of programming). In one sense, it just means grouping
data and methods together. In another sense, it means restricting the
client's access to data or methods. Someone earlier on this thread
tried to claim that the first meaning applies to OOP, but Wikipedia
(and many other sources) say just the opposite.
People here are trying to claim that the leading underscore
conventions used with Python are essentially equivalent to
encapsulation. That is nonsense, of course.
Others are arguing against encapsulation altogether. That is a bit
like being against locks or passwords because they create a lot of
hassle. Now locks are not needed everywhere, of course, but certainly
they have their place. But the point is that if you don't like
encapsulation, then by definition you don't like OOP. You may like
certain features of OOP, but you don't like it in general. That's
about all their is to it.
And by the way, please don't bring up the canard that I am some kind
of OO zealot. I think OO is overrated, and I don't Java, in part
because it forces everything to be OO. The issue here is not my
personal opinion of OOP. This issue is one of widely accepted
definitions within the OO community.
> Remember that it is a model and not a strict set of requirements that
> programming
> languages must implement.
Of course it's not a "requirement that programming languages must
implement." It's only a requirement if they want to be OO languages.
You're kidding, right? Think about a ten-million line program being
developed by 100 developers.
>> Give me one use-case where you strictly require
>> that members of an object be private and their
>> access enforced as such ?
>
> You're kidding, right? Think about a ten-million line program being
> developed by 100 developers.
No I"m sorry this is not a valid use-case.
cheers
James
> You know what? Computer science buzzwords mean jack squat to me. I
> don't give a horse's tail whether some people label it a fundamental
> concept of object-oriented programming or not. I think it's a bad
> thing. And it's a bad thing for exactly the reason I said: it gives
> the library implementor the power to dictate to the user how they can
> and can't use the library. The cultural impact that would have on the
> community is far worse, IMHO, than any short-sighted benefits like
> being able to catch an accidental usage of an internal variable.
> Trust would be replaced by mistrust, and programming in Python would
> go from a pleasant experience to constant antagonism.
>
> No thanks. "Software engineering" be damned. Python is better off
> the way it is.
You know what? The more I think about the kind of nonsense you and
others are spouting here, the more annoyed I get. I will gladly agree
that encapsulation may be more trouble than it's worth for small
applications, maybe even some medium sized ones, but you and others
here are making blanket proclamations that are just plain nonsense.
I suggest you call Boeing and tell them that encapsulation is more
trouble than it's worth for their 787 flight software. But please
don't do it if you ever wish to work for them, because you will be
proving conclusively that you don't have a clue about the kind of
software systems they produce.
I've wasted more than enough time with this nonsense.
Russ:
1. Quit while you're ahead.
2. OOP is encapsulating data and functionality into a single grouping (object).
3. Other features more recently developed by OO languages such as
Polymorphism, Access Control (a type of encapsulation), Inheritance
and Multiple Inheritance are all irrelevant and OO languages either
implement all or a subset of these features and each do so
differently.
Fundamentally it all boils down to4 things (which all of you -
including you Russ - just completely miss the point):
READ
UPDATE
ADVANCE
These are the 3 operations of a Turing machine of which all
computer algorithms can be defined. We usually define a 4th operation
called HALT.
Now go ponder on that a while and come back and tell
me whether you think you really need such things as
Abstract Base Classes, Interfaces, Access Control,
Static Typing, and so on and so forth ...
>> Give me one use-case where you strictly require
>> that members of an object be private and their
>> access enforced as such ?
>
> You're kidding, right? Think about a ten-million line program being
> developed by 100 developers.
And what is your point exactly ? Like I said, this is _not_ a valid
use case. A language that implements all of the features descirbed
in academic texts on OOP will not help you build such a system
any faster.
I should also point out that building such a system in Python would
most likely result in 1/3 of the size in terms of LoC.
I should also point out that your numbers you pulled out of your
hat would require 22years of development time given the industry
standard of 5 LOC/hg per developer. Good luck with that.
cheers
James
I am 100% confident that those same systems could be
well written in a language such as Python and would very
likely end up being much smaller and more manageable.
I have a question for you:
All your arguments seem to lean towards size and the
importance of encapsulation. What is the largest system
you have worked on - that has been written entirely in Python ?
cheers
James
It's the other way around. If the compiler knows that you aren't
creating new attributes on the fly, it can put them into fixed slots
like a C struct, and method calls become ordinary function calls
through a dispatch vector.
Paul I wasn't referring to static languages and
languages that are compiled to machine code such
as C, C++, etc.
Python is a dynamic object oriented language ...
(almost verbatim from the website). It is compiled
to bytecode and run on a virtual machine.
I don't really think it would be possible or
desirable to have strict access control (encapsulation)
in the core of python.
a) it would piss us all off.
b) it would greatly impact on the dynamic nature of python.
cheers
James
Why not? Just saying it isn't doesn't make it not.
--
Steven
1. There is nothing inherent about dynamic languages that prevents
them from being compiled. There are compiled implementations of
Lisp and Scheme that beat the pants off of Python in performance.
2. There is also nothing inherent in a dynamic OO language that says
that class descriptors have to be mutable, any more than strings have
to be mutable (Python has immutable strings). I agree that being able
to modify class descriptors at runtime is sometimes very useful. The
feature shouldn't be eliminated from Python or else it wouldn't be
Python any more. But those occasions are rare enough that having to
enable the feature by saying (e.g.) "@dynamic" before the class
definition doesn't seem like a problem, both for encapsulation
and because it can also improve performance.
That's funny. I worked for four years at a GE Aviation subcontractor
on their jet engine control software, so I think do I have a clue
about how flight control software systems work.
At GE there was no encapsulation in sight on any system I worked on.
In fact, our engine simulation was a special-purpose object-oriented
language with--get this--no private variables. Some other systems I
worked on didn't even use scoping, let alone encapsulation.
Looks like my anecdote cancels out yours! Got any more?
Carl Banks
Which is all well and good, but there are circumstances where you *don't*
want to trust arbitrary parts of your code to change other parts of your
code, for good reason. In other words, you don't always want to trust
your users.
Forget copy protection and DRM. Think about the software controlling a
radiation machine for cancer treatment, with a limit on the number of
rads it fires at any one time. It would be disastrous for any arbitrary
function in the machine's software to be able to mess with that limit,
accidentally or deliberately. People will die if you get it wrong.
My attitude when programming in Python is to accept that if the caller
passes an inappropriate argument to my function, my function may crash
(raise an exception). That's the caller's responsibility. I can get away
with this laissez faire attitude because I don't have to worry about my
software crashing at the wrong time and causing a plane filled with 500
nuns and orphans suddenly flip upside down and nose-dive into a mountain.
Or the nuclear reactor to suddenly drop all the fuel rods into the core
simultaneously. Sometimes "oh, just raise an exception and exit" is
simply not good enough.
Security/safety and freedom/flexibility are sometimes in conflict. There
are plenty of languages which enforce access. It is a good thing that
Python allows more flexibility. That's why I use Python. The traditional
answer to this "if you need Java, you know where to get it".
But, gosh darn it, wouldn't it be nice to program the critical parts of
your code in "strict Python", and leave the rest as "trusting Python",
instead of having to use Java for the lot just to get strictness in the
critical parts? If only there was a way to do this, and ensure people
won't abuse it.
--
Steven
Where my officemate used to work, the simulation stuff was written in
Matlab, but the actual flight stuff was written in Ada. I wonder
if GE did something similar.
I'm on record saying Python shouldn't be used for systems with the
possibility of catastrophic failure: that's with or without
encapsulation. Too much happening internally to account for it all.
Frankly I'm not sure that C++ and Java's encapsulation is good enough,
either. Software-enforced encapsulation can be subverted, and
sometimes invalid access can happen from within the protection zone.
If something's that important, it needs to be running with redundancy
and lots and lots of fault tolerance, and it needs to have the hell
tested out of it. If it's critically important, the code should be
storing the critical information in a separate data area with a higher
privledge level than the rest of the program. The simpleminded
encapsulation schemes of C++ and Java are weak compared to these
methods, and probably wouldn't add much.
As I said, I've worked on flight control systems that didn't use any
data hiding at all. Even if a drastic coding mistake like you
mentioned was able to make it though dozens of peer reviews and
hundreds of tests, it still might not result in catastrophic failure
because of all the fault tolerance built-in.
Carl Banks
I was going to suggest the same thing. An engine *simulation* is one
thing; the actual engine control code is another. And the interface
between the engine control code and the rest of the flight software is
yet another. The FMS should be setting the throttle level, but I doubt
it should be fooling around with the guts of the engine control
software.
> But, gosh darn it, wouldn't it be nice to program the critical parts of
> your code in "strict Python", and leave the rest as "trusting Python",
> instead of having to use Java for the lot just to get strictness in the
> critical parts? If only there was a way to do this, and ensure people
> won't abuse it.
Yes, that would indeed be nice. I am certainly not the only one who
could use a language that is excellent for both research prototyping
*and* the final, safety-critical system. Then perhaps the prototype
could just be cleaned up and "hardened" for the end product rather
than rewritten in another language -- by programmers in another state
who may fail to understand many of the details that the prototype
developer agonized over.
I don't know if such a versatile language could even exist, but it
would sure be valuable. Maybe it's like asking for a football player
who can excel as both a wide receiver and a guard. But players who
weigh 280 pounds and run a 4.4 40 are hard to find.
I thought you were done wasting time with this nonsense.
> An engine *simulation* is one
> thing; the actual engine control code is another.
Guess what systems I worked on that didn't even use scoping? I wrote
code for the GP7000 (equipped on some Airbus 380s) and the F-136
(which will be equipped on some F-35 fighters) engine controllers.
Neither one used any data hiding. The language was C (not C++), but
it was generated from schematic diagrams.
Would you like to adopt GE's practice of schematic-generated C with no
namespaces or data hiding? No? Then don't be telling me I have to
embrace Boeing's.
Carl Banks
I do feel concerned by these issues.
> I'm not a computer scientist, but it seems to me that
> Python is great for hacking and good for software engineering, but it
> is not ideal for software engineering.
>
> What Paul is suggesting, I think, is that Python should move in the
> direction of software engineering. Whether that can be done without
> compromising its hacking versatility is certainly a valid question,
> but if it can be done, then why not do it?
>
> Certainly one basic principle of software engineering is data
> encapsulation. Tacking new attributes onto class instances all over
> the place
There's a clear distinction between "making wise use of dynamicity" and
"tacking new attributes onto class instances all over the place".
> may be convenient and useful in many cases, but it is not
> consistent with good software engineering.
simplicity is "good software engineering". Accidental complexity is not.
Dynamism _can_ greatly reduce accidental complexity.
> If the programmer could
> somehow disallow it in certain classes,
Already possible - you just have to provide your own implementation of
__setattr__.
> that could be useful,
> providing that those who wish to continue doing it would be free to do
> so. If class attributes could somehow be declared private,
The important point is to make implementation distinct from interface -
which we already know how to do -, and sometimes to prevent _accidental_
overriding of some critical implementation attributes - which is also
already implemented. Enforcing access restriction is, from experience,
just pointless.
"""
patient : doctor, when I do this, it hurts
doctor : well, don't do it, then.
"""
Because "developer" means people who don't mess with implementation
details. So they respect the leading underscore convention. No use case
for enforced access restriction.
Ciao,
Marc 'BlackJack' Rintsch
The question is where such checks should be. Guido prefers separate
checkers (PyChecker, PyLint) rather than in the interpreter. If you
think they are incomplete, help improve one of them.
O rly? *raise eyebrow*
http://www.clausbrod.de/cgi-bin/view.pl/Blog/
WebHome#DefinePrivatePublic20080413_This
Sometimes developers have to work around encapsulation in their own code:
http://www.gamedev.net/community/forums/topic.asp?topic_id=386856
Sometimes they do it just because they can:
http://java-interview-faqs.blogspot.com/2008/08/hacking-by-reflection-
accessing-private.html
or http://snipurl.com/a0tox
And try this:
http://www.google.com/codesearch?q=%22%23define+private+public%22
--
Steven
Part of the idea of non-dynamic attribute sets is to make the program
run faster, not slower.
> On Jan 13, 11:40 pm, Steven D'Aprano
> <ste...@REMOVE.THIS.cybersource.com.au> wrote:
>
>> But, gosh darn it, wouldn't it be nice to program the critical parts of
>> your code in "strict Python", and leave the rest as "trusting Python",
>> instead of having to use Java for the lot just to get strictness in the
>> critical parts? If only there was a way to do this, and ensure people
>> won't abuse it.
>
> Yes, that would indeed be nice. I am certainly not the only one who
> could use a language that is excellent for both research prototyping
> *and* the final, safety-critical system. Then perhaps the prototype
> could just be cleaned up and "hardened" for the end product rather
> than rewritten in another language -- by programmers in another state
> who may fail to understand many of the details that the prototype
> developer agonized over.
You might have a look at Business Shell <http://www.pegasoft.ca/bush.html>
which is based on Ada.
Mel.
Why don't you do it backwards?
You *can* implement a metaclass that will remove the dynasmism from its
instances. Do it - I can give you a starting point if you wish.
But most of us are very happy with the dynamic nature of python... I chose
python _because_ of it.
> and because it can also improve performance.
Btw, for performance, there is __slots__, with the side-effect that it forbids
attribute creation 'on the fly'.
--
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie
Aren't the last two reversed?
protected = one leading underscore
[both you and your subclasses should access it]
private = two leading underscores (name munging)
[only you should access - implementation detail.]
Devil's advocate here - I think I can give you one:
when you need to share some objects with potentially untrusted code (like, a
plugin system). You can't, and you shouldn't, expect that the user will know
what plugins he should or shouldn't load, and you shouldn't blame him/her
when your app stops working because you failed to protect it's internals from
malicious plugins (think web browser).
Of course... in that scenario, the public/private distinction is the least of
the concerns... and whatever is done to solve them will likely make
irrelevant if the members are private or public.
But, for trusted code? Or at least code known at compile time? It's just not
worth it... pylint should take care of that - and if it doesn't, the OP
should go fix it.
Python is not set up for this even slightly. Java attempts it, with
mixed success.
To further your point, I'd say that python _doesn't_ have polymorphism. It
doesn't need it - the natural, expected, "OOP" behavior is always there, you
cannot break it. A dog will always bark and a cat will always meow,
regardless of the context and the inheritance relation between a cat and a
dog (there should be none, but I couldn't think of a better example than the
broken 'a cat is a dog'... please bear with me). If the very concept of
polymorphism is superfluous in python, would that make python 'less' OOP?
Judging by this thread, I'd guess that Russ believes that languages like C#
are closer to his OOP ideal... and guess what, C# not only needs a word for
the concept of "objects should behave as you expect them to behave - we want
no barking cats, ever", but it is even not polymorphic by default (the
cursed "virtual" keyword).
Again, there have to be some language extensions to communicate the
necessary info to the external tool. Python 3.0 begins to do that,
but as others have mentioned, it's still in a formative state while we
get more experience with it. The other angle is that the compiler can
use static knowledge about the program to make the program run faster,
so if the checks are in an external tool, there has to be
communication in both directions to make use of that.
That's kind of interesting, how does it work?
> But most of us are very happy with the dynamic nature of python... I chose
> python _because_ of it.
I like it too, since it is indispensable in some situations. But,
those situations are uncommon enough that I don't mind typing a few
extra keystrokes to turn the dynamism on.
> Btw, for performance, there is __slots__,
That is a good point, we somehow lost sight of that in this thread.
> with the side-effect that it forbids attribute creation 'on the
> fly'.
I have had the impression that this is a somewhat accidental side
effect and shouldn't be relied on.
Russ argument was about "good engineering", not about raw perfs. FWIW,
_you_ may be willing to trade dynamism for raw perfs, but there are
probably some people here that won't agree.
Given that the convention for "protected" attributes in Python is to
prefix them with an underscore, I fail to see how one could
"accidentally" mess with implementation details. Typing a leading
underscore is rarely a typo.
Oh, BTW, IIRC, there are a couple lint-like apps for Python, some of
them being able to warn you about most of these (potential) problems.
Obviously there will never be total unanimity about every tiny thing.
I haven't anywhere in this thread as far as I know suggested
eliminating dynamism from Python, which would be in "that's not Python
any more" territory. But, in the dozens of class definitions I write
in any given day of coding, I might use the dynamism we're talking
about in 1% of them at most. If having to type a few extra keystrokes
on that 1% improves program reliabiity AND performance, it certainly
seems worth it to me.
We are talking about the accidental creation of new attributes in
places outside the initializer. The underscore convention does
nothing to prevent that.
I know. I find it sad, though. Also, I find it not a priority.