Re: Encapsulation unpythonic?
Fabrice Pombet於 2013年8月31日星期六UTC+8上午1時43分28秒寫道: On Saturday, August 17, 2013 2:26:32 PM UTC+2, Fernando Saldanha wrote: I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. Questions: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Fernando, it is widely accepted that Python pays very little attention to encapsulation as a principle set in stone. Chaz's definition of encapsulation is also mine. Now you need to consider that taking this principle off the hostel of OOP does not mean that you can do whatever you fancy and you can't make anything unsettable. There are plenty of techniques within Python that allow you to protect your arguments (in particular, decorators) inside a Class. Now, lets get to the pretentious philosophical discussion: I guess encapsulation is quite the opposite of, say, dynamic typing, which is arguably core in Python. In practice this allows Python to be less verbose: at the end of the day, if you look back at your previous languages, don't you find that some of their compulsory features are usually more of a pain than something useful in practice? And after all, whither encapsulation? Can't we just have objects whose arguments are determined externally if we want to? And that is the ballgame: as my old tutor says: the claptrap of setters and getters does not need to be here if it is unnecessary. I would add: so long as you can have them when you deem it necessary, and Python allows that. The way to perform encapsulation in Python can be achieved by writing methods in C to be compiled as an extension which can be used by all instances of some classes in the upper level. CYTHON is easy to be used for the job. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sat, 31 Aug 2013 12:46:52 +0100, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: # THIS DOES NOT HAPPEN IN PYTHON # or any other language, as far as I am aware x = 23 y = x # y now has the value 23 x = 42 # change the value of the object ### NOT SO! ### print y = prints 42 Not directly, but FORTRAN did (does?) allow you to achieve this oh-so-undesirable result indirectly. FORTRAN passes arguments to functions and procedures by reference. That includes passing constants, which effectively get put into hidden variables and passed across. Changes to the constant parameters in the function can happen just as with any pass-by-reference, which would be fine if you promptly threw the constant away. Unfortunately smart compilers used to (still do?) keep pools of these common constant variables around rather than creating new ones all the time, so changes to constants persisted. Many's the poor natural scientist who was perplexed to find that 0 suddenly had the value 1! -- Rhodri James *-* Wildebeest Herder to the Masses -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sat, 31 Aug 2013 05:57:47 -0700, Fabrice Pombet wrote: Steve, I think that your definition of encapsulation is too wide to give a reasonable answer to the question at hand. My definition of encapsulation is based on the plain language definition. It is also common in computer programming circles to talk about encapsulation in this way. OOP designers may (or may not) have been the first to declare encapsulation was a design principle, but programmers have been using the *principle* of encapsulation since before Grace Hopper was an admiral. See, for example, coders talking about encapsulation in C and Powershell: http://ejrh.wordpress.com/2011/04/29/encapsulation-in-c/ https://www.simple-talk.com/dotnet/.net-tools/further-down-the-rabbit- hole-powershell-modules-and-encapsulation/ OOP languages give us *more* and *better* ways to encapsulate code and data, but they did not invent the principle. If I understand you correctly, you are taking encapsulation as a language characteristic, rather than a principle. No, it is both. The coder may or may not decide to encapsulate code in subroutines/functions/classes, and the language may or may not allow it. Languages differ in their ability to allow the programmer to encapsulate. Some languages, like early BASIC, give you no ability to encapsulate code or data at all. All variables are global, and there are no functions, just a big blob of code in a single file. There aren't even data structures as such, except strings, so you cannot even group related pieces of data into a struct or record. Some languages, like Python, give you many ways to encapsulate code and data: you can group related code in a function, related functions in a class, related classes in a module, related modules in a package. That's pretty much exactly the same sort of things that you can do in Java. C++ has an additional namespace data structure that Python doesn't have, but that's just a mechanism for encapsulation. Encapsulation and information hiding are distinct things -- you can have one without the other. C, for example, creates a new scope inside for- loops, so that the for-loop variable is hidden from the rest of the function. Apart from a pair of braces, there is no encapsulation, but there is information hiding. Or you could design a language that encapsulated code into functions and classes, but put all variables in a single, global, shared namespace (little, or no, information hiding). It is a myth, and a very obnoxious one, that encapsulation and information hiding were invented by OOP. What is a function but a way to hide the implementation of a chunk of code from the caller? What are local variables but a way to hide variables used by one function from another? Coders were using information hiding, separation of concerns, and encapsulation in the 1950s, long before OOP. They just didn't call them by those names. They just called them writing good code. Actually, functions are *not necessarily* a way to hide implementation. There are languages where you can jump into the middle of a function. So you can encapsulate a chunk of code into a function, without hiding the implementation details. Just as you can encapsulate code and data into a class, without hiding the implementation details, if you declare everything public. Plus, you seem to forget that encapsulation is an OOP principle, and, forgive me if I am wrong, does not apply normally to functions or languages like C. I haven't forgotten it, because it isn't true. One of the most obnoxious and annoying traits of OOP zealots, especially academics, is that they act as if programming did not exist before Java and C++, or if you're really lucky, Smalltalk. (Somehow they nearly always forget about Simula.) Perhaps because OOP was so late to be invented (structured programming goes back to Fortran in the 1950s, functional programming to Lisp only a few years after that), and because it was so heavily hyped as the solution to every programming difficulty, too many people ignore anything outside of the OOP. They wrongly believe that since Python isn't a pure OOP language (according to some bizarre understanding of pure that often considers C++ and Java pure), Python cannot possibly have OOP principles like encapsulation, information hiding, separation of concerns. That point of view is sheerest nonsense. Please read Steve Holden's (in chaz') definition, and tell us whether you think that Python enforces strongly this principle, I think that would be a good basis for an agreement. Are you referring to this quote? encapsulation is the idea that the only way to access or change the data inside an object is by calling its methods. I disagree with that definition. That's a poor definition, one that has no relation to the plain English meaning of the word encapsulation, nor to how the word is commonly used in the great bulk of programming circles. By
Re: Encapsulation unpythonic?
On Sun, Sep 1, 2013 at 6:10 PM, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: Java and C++ allow you to declare members as public, so it is *not true* that calling methods is the only way to change members. If you accept Steve Holden's (wrong) definition above, Java and C++ don't have encapsulation either. That said, though, when you consider the language ecosystem rather than just the language, there is a strong tendency for Java and C++ code to wrap everything up with functions (no public data members), whereas Python code is far more likely to have external code directly access data inside an object. You usually will find Java code calling methods to change members, whereas that's done in Python only when there's a need for it. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
That said, though, when you consider the language ecosystem rather than just the language, there is a strong tendency for Java and C++ code to wrap everything up with functions (no public data members), whereas Python code is far more likely to have external code directly access data inside an object. You usually will find Java code calling methods to change members, whereas that's done in Python only when there's a need for it. Yep, this is precisely my point, if you take encapsulation as a philosophical principle, Java and C++ would tend to be abiding by it, as a default setting that you can at times change, whereas python would tend to be the contrary. In other words, you can set some encapsulation if and when you want to, but you can leave your code without it when it's not needed/inconvenient. So I guess that we are actually all agreeing on this one. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 09/01/2013 03:09 AM, Fabrice Pombet wrote: So I guess that we are actually all agreeing on this one. No, we are not. encapsulation != inaccessible except by getters/setters -- ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
In article mailman.455.1378062400.19984.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: On 09/01/2013 03:09 AM, Fabrice Pombet wrote: So I guess that we are actually all agreeing on this one. No, we are not. encapsulation != inaccessible except by getters/setters Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name :-) -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 09/01/2013 12:13 PM, Roy Smith wrote: In article mailman.455.1378062400.19984.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: On 09/01/2013 03:09 AM, Fabrice Pombet wrote: So I guess that we are actually all agreeing on this one. No, we are not. encapsulation != inaccessible except by getters/setters Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name :-) class Javaesque: __value = None def get_value(self): return self.__value def set_value(self, new_value): validate(new_value) self.__value = new_value class ProtectedPython: _value = None @property def value(self): return self._value @value.setter def value(self, new_value) validate(new_value) self._value = new_value class PlainPython: value = None In the Javaesque class we see the unPythonic way of using getters/setters; in the ProtectedPython* class we see the pythonic way of providing getters/setters**; in the PlainPython class we have the standard, unprotected, direct access to the class attribute. No where in PlainPython is a getter/setter defined, nor does Python define one for us behind our backs. If you have evidence to the contrary I'd like to see it. * Not the best name, but oh well. ** In Python, using @property makes getter/setter usage look just like normal attribute usage, which is cool. -- ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 2 September 2013 06:33, Ethan Furman et...@stoneleaf.us wrote: class PlainPython: value = None In the Javaesque class we see the unPythonic way of using getters/setters; in the ProtectedPython* class we see the pythonic way of providing getters/setters**; in the PlainPython class we have the standard, unprotected, direct access to the class attribute. No where in PlainPython is a getter/setter defined, nor does Python define one for us behind our backs. If you have evidence to the contrary I'd like to see it. I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Tim Delaney -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
In article mailman.461.1378072496.19984.python-l...@python.org, Tim Delaney timothy.c.dela...@gmail.com wrote: On 2 September 2013 06:33, Ethan Furman et...@stoneleaf.us wrote: class PlainPython: value = None In the Javaesque class we see the unPythonic way of using getters/setters; in the ProtectedPython* class we see the pythonic way of providing getters/setters**; in the PlainPython class we have the standard, unprotected, direct access to the class attribute. No where in PlainPython is a getter/setter defined, nor does Python define one for us behind our backs. If you have evidence to the contrary I'd like to see it. I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Tim Delaney Thank you. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
Steven D'Aprano steve+comp.lang.pyt...@pearwood.info writes: […] programmers have been using the *principle* of encapsulation since before Grace Hopper was an admiral. […] Encapsulation and information hiding are distinct things -- you can have one without the other. […] One of the most obnoxious and annoying traits of OOP zealots, especially academics, is that they act as if programming did not exist before Java and C++, or if you're really lucky, Smalltalk. (Somehow they nearly always forget about Simula.) Yes. That's something which has been pointed out to such people, even in the Java community, for most (all?) of Java's history. Here's a JavaWorld article from 2001, by a Java programmer, with the clear title “Encapsulation is not information hiding”: Encapsulation refers to the bundling of data with the methods that operate on that data. Often that definition is misconstrued to mean that the data is somehow hidden. URL:http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html (That site unfortunately slices up the article into many pages to increase advertising hits and reader frustration, my apologies.) One of the more annoying traits of humanity is that whatever context we first encounter a term is disproportionately privileged, causing us to irrationally dismiss better (more useful, more reasonable, more pedagogically appropriate, more historically correct, etc.) definitions. This thread is an excellent illustration that the field of programming is no exception. -- \ Moriarty: “Forty thousand million billion dollars? That money | `\must be worth a fortune!” —The Goon Show, _The Sale of | _o__) Manhattan_ | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 09/01/2013 02:54 PM, Tim Delaney wrote: Roy Smith wrote: Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Seems to me there is a difference between an underlying generic protocol for data manipulation and Python writing them [getters/setters] for you. -- ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
In article mailman.464.1378078348.19984.python-l...@python.org, Ben Finney ben+pyt...@benfinney.id.au wrote: One of the more annoying traits of humanity is that whatever context we first encounter a term is disproportionately privileged, causing us to irrationally dismiss better (more useful, more reasonable, more pedagogically appropriate, more historically correct, etc.) definitions. Known in the education world as The law of primacy. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
In article mailman.468.1378083075.19984.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: On 09/01/2013 02:54 PM, Tim Delaney wrote: Roy Smith wrote: Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Seems to me there is a difference between an underlying generic protocol for data manipulation and Python writing them [getters/setters] for you. Why? When I write foo.bar, a bunch of generic code gets run which figures out what value to return. If I don't like the generic behavior, I can write my own __getattrr__(), etc, and make it do whatever I want. How is that any different from, in C++, if you don't write a default constructor, the compiler will write one for you. If you don't like the generic behavior you get from that, you can write your own and make it do whatever you want. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sun, 01 Sep 2013 15:13:06 -0400, Roy Smith wrote: In article mailman.455.1378062400.19984.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: On 09/01/2013 03:09 AM, Fabrice Pombet wrote: So I guess that we are actually all agreeing on this one. No, we are not. encapsulation != inaccessible except by getters/setters Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name :-) Very clever! Pedantic, and an unusual look at what's going on under the hood! I wanted to say it was *not quite correct*, because you can read or write directly to the instance dict: instance.__dict__['name'] = 42 If I understand Python's internals correctly, __dict__ is a slot, and so bypasses the usual getattr machinary. But even if so, __dict__['name'] uses the dictionary __get/setitem__ method, so it's still a getter/setter under the hood. In any case, even if you are *technically* correct that Python has getters and setters under the hood, that's not quite what the discussion here is about. But I'm sure you realise that :-) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sun, 01 Sep 2013 20:59:25 -0400, Roy Smith wrote: In article mailman.468.1378083075.19984.python-l...@python.org, Ethan Furman et...@stoneleaf.us wrote: On 09/01/2013 02:54 PM, Tim Delaney wrote: Roy Smith wrote: Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Seems to me there is a difference between an underlying generic protocol for data manipulation and Python writing them [getters/setters] for you. Why? When I write foo.bar, a bunch of generic code gets run which figures out what value to return. If I don't like the generic behavior, I can write my own __getattrr__(), etc, and make it do whatever I want. How is that any different from, in C++, if you don't write a default constructor, the compiler will write one for you. If you don't like the generic behavior you get from that, you can write your own and make it do whatever you want. And fundamentally, all programming is flipping bits, therefore all languages are exactly the same, right? :-) I can't speak for C++, but comparing Java and Python there are differences: - Java the language makes it a pain to change your mind and convert a public attribute to a computed attribute. Since the pain of changing your mind far outweighs the pain of writing trivial getters/setters up front, it is good defensive practice to make attribute access via getters just in case. Python makes it trivial to change your mind, and so YAGNI rules and you shouldn't write getters unless you actually need them. - Perhaps because the focus in Java is on massive projects with large numbers of barely adequate coders, Java tries to protect the average coder from shooting themselves in the foot. Consequently, Java encourages a philosophy of default deny when it comes to attribute access: don't give your caller access to anything except the absolute minimum you know they need. In Python, the focus tends to be more about smaller projects with small teams of better than average coders, and a philosophy of we're all adults here. Consequently, Python code tends towards everything not explicitly prohibited is permitted. - Similarly, while Java the language doesn't force you to *explicitly* declare members as public (if you don't declare members private, they are public), it strongly encourages you to think about information hiding and explicitly mark members as public. Python does not. There is no way to explicitly mark attributes as public. - The Java compiler enforces public/private, while Python treats it as a convention. (At least for pure-Python code.) But notice that they are differences of degree, not kind. Java encourages information hiding in classes, but does not prohibit you from making members public, and using reflection you can break into classes and get access to anything; Python allows information hiding, but trusts the programmer to honour private names, and reflection is such a fundamental part of Python that we don't even call it that. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 09/01/2013 05:59 PM, Roy Smith wrote: Ethan Furman wrote: On 09/01/2013 02:54 PM, Tim Delaney wrote: Roy Smith wrote: Nothing is accessible in Python except via getters and setters. The only difference between Python and, say, C++ in this regard is that the Python compiler writes them for you most of the time and doesn't make you put ()'s at the end of the name I think Roy is referring to the fact that attribute access is implemented via __getattr__ / __getattribute__ / __setattr__ / __delattr__. From one point of view, he's absolutely correct - nearly all attributes are accessed via getters/setters in Python. Seems to me there is a difference between an underlying generic protocol for data manipulation and Python writing them [getters/setters] for you. Why? When I write foo.bar, a bunch of generic code gets run which figures out what value to return. If I don't like the generic behavior, I can write my own __getattrr__(), etc, and make it do whatever I want. I don't yet know C++ so I can't speak to it. In Python if you are writing your own __getattr__, etc., you are writing the underlying protocol itself. To write a getter/setter you would just use def get_soemthing(...) def set_something(...) or, even better @property def something(...) Maybe, as Steven said, it's just a matter of degree: my understanding of getters/setters is that they are per attribute, while __getattr__ will be called for every attribute not otherwise found, __setattr__ will be called for every assignment, __delattr__ will be called for every deletion, and all that is assuming you haven't written your own __getattribute__ and completely changed the rules for your class. -- ~Ethan~ -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 31, 2013 4:35:39 AM UTC+2, Steven D'Aprano wrote: On Fri, 30 Aug 2013 10:43:28 -0700, Fabrice Pombet wrote: On Saturday, August 17, 2013 2:26:32 PM UTC+2, Fernando Saldanha wrote: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Fernando, it is widely accepted that Python pays very little attention to encapsulation as a principle set in stone. Widely accepted by whom? most people(except you, apparently, but I fear that you do not really accept in general) Python code is *full* of encapsulation. Functions, methods, classes, modules, packages, even local variables, are all mechanisms for encapsulating code and data. Those who say that Python has little or no encapsulation are talking rubbish. Chaz's definition of encapsulation is also mine. Who is Chaz, and what definition does he have? See above me chaz...@gmail.com, the definition of encapsulation from his OST course is fine by y standards, quoting him: I'm taking the Python Cert series w/ O'Reilly School of Technology, which I recommend if you've got a good handle on OO programming. In any event, according to what I've learned, encapsulation is the idea that the only way to access or change the data inside an object is by calling its methods. This idea has never really gained much ground in the Python world, and it is normally considered acceptable to both read and set an object's attributes from anywhere in a program. Keep in mind that we are talking about Encapsulation(a general/philosophical principle) as opposed to encapsulating (i.e. setting an argument so that it can only be read/written from within its class/object) this is a key conceptual point. I agree with you that Python allows you to enforce the encapsulation principle within your code, whenever you want it. But not as a principle that you NEED to respect(as in Java for instance). It is, in my opinion, much better this way. And now you are talking about information hiding and protection, which is not the same of encapsulation, no matter what the academics think. Sometimes the air gets a bit too thin to breathe way up at the top of those ivory towers... I am no academic, and I think that's right. Encapsulation is about grouping code that needs to be together together. In contract, you have programming languages that give you little, or nothing, in the way of grouping -- everything is one big chunk of code, with GOTO or GOSUB to jump from place to place. I think that I prefer chaz' definition (it is, how could I put it... A tad easier to understand) Functions and procedures are the first, most simple, form of encapsulation. Classes allow you to encapsulate multiple functions (methods) together with the data they need to operate on in one chunk. Even in C++ or Java, you can have classes that provide no information hiding at all -- just declare everything public. On the other hand, non-OOP languages like C can implement information hiding. In C, you can hide information from other files by declaring them as static. Variables declared inside a brace-delimited block only exist within that block: local variables are hidden. For example: int foo; static int bar; bar is hidden from other files. Likewise, in this function: int func(void) { int baz; ... } baz is local to func, and invisible to any other function. So you can have information hiding without classes, and classes without information hiding. The two concepts are obviously independent, but as usual, the academics who are in love with OOP like to pretend that anything that is of any interest whatsoever in computing was invented by Java and C++. There are even languages with functions, but no local variables. For instance, older versions of Forth let you define functions, what Forth calls words, but all functions operate on the same global stack. Python has excellent encapsulation: we can combine code that ought to be together into a function, related functions into a class, related classes into a module, and related modules into a package. Now, lets get to the pretentious philosophical discussion: I guess encapsulation is quite the opposite of, say, dynamic typing, which is arguably core in Python. They are utterly unrelated. Dynamic typing has nothing to do with whether or not you can encapsulate code into chunks (subroutines, functions, modules, classes...) or whether you have to write one big amorphous unstructured program where every chunk of code can reach inside other chunks of code. Nor does dynamic type have to do with information hiding. You can
Re: Encapsulation unpythonic?
On 08/31/2013 08:07 AM, Fabrice Pombet wrote: well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. No, `a` is not an object, so you did not change the type of any object. `a` is just a name (a label), that initially refers to the tuple (1, 2): a = (1, 2) id(a) 140377464514968 ad after, to another object, of type int: a = 2 + 3 id(a) 8752608 The bytecode: dis.dis('a = (1, 2); a = 2 + 3;') 1 0 LOAD_CONST 4 ((1, 2)) 3 STORE_NAME 0 (a) 6 LOAD_CONST 5 (5) 9 STORE_NAME 0 (a) 12 LOAD_CONST 3 (None) 15 RETURN_VALUE Regards, M. -- Marco Buttu -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 08/30/2013 11:07 PM, Fabrice Pombet wrote: ... long discussion elided ... well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? Yes, in fact you can do that in C++ and java: Obj1 a = ...some object...; { // new scope... Obj2 a = ...another object...; } On one line, the name 'a' is bound to one object, and later it is bound to another object. Your Python code is similar, binding the name 'a' to object (1,2) on one line and the object 5 on the next line. Granted, Python seems a little freer because, with it's dynamic typing, one doesn't need to create a new scope to rebind a name, but all languages with variable names allow some control over binding/rebinding names. But this has *nothing* at all to do with objects and encapsulation. Please don't confuse: the binding of names to objects and the existence of objects and their encapsulated behavior They are very different things. -- Dr. Gary Herron Department of Computer Science DigiPen Institute of Technology (425) 895-4418 -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 31, 2013 9:03:58 AM UTC+2, Gary Herron wrote: On 08/30/2013 11:07 PM, Fabrice Pombet wrote: ... long discussion elided ... well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? Yes, in fact you can do that in C++ and java: Obj1 a = ...some object...; { // new scope... Obj2 a = ...another object...; } On one line, the name 'a' is bound to one object, and later it is bound to another object. Your Python code is similar, binding the name 'a' to object (1,2) on one line and the object 5 on the next line. Granted, Python seems a little freer because, with it's dynamic typing, one doesn't need to create a new scope to rebind a name, but all languages with variable names allow some control over binding/rebinding names. But this has *nothing* at all to do with objects and encapsulation. Please don't confuse: the binding of names to objects and the existence of objects and their encapsulated behavior They are very different things. -- Dr. Gary Herron Department of Computer Science DigiPen Institute of Technology (425) 895-4418 That's interesting, can you do this in C++ or java: class X(): -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 31, 2013 9:42:55 AM UTC+2, Fabrice Pombet wrote: On Saturday, August 31, 2013 9:03:58 AM UTC+2, Gary Herron wrote: On 08/30/2013 11:07 PM, Fabrice Pombet wrote: ... long discussion elided ... well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? Yes, in fact you can do that in C++ and java: Obj1 a = ...some object...; { // new scope... Obj2 a = ...another object...; } On one line, the name 'a' is bound to one object, and later it is bound to another object. Your Python code is similar, binding the name 'a' to object (1,2) on one line and the object 5 on the next line. Granted, Python seems a little freer because, with it's dynamic typing, one doesn't need to create a new scope to rebind a name, but all languages with variable names allow some control over binding/rebinding names. But this has *nothing* at all to do with objects and encapsulation. Please don't confuse: the binding of names to objects and the existence of objects and their encapsulated behavior They are very different things. -- Dr. Gary Herron Department of Computer Science DigiPen Institute of Technology (425) 895-4418 That's interesting, can you do this in C++ or java: class X(): def __init__(self, *arg): for x in arg: self.x=x and then: a=X(x,y,z) and then: a.w=w ? I guess my point was dynamic typing and encapsulation go a little in opposite directions in terms of philosophy, and it is therefore clear that Python privileges dynamic typing kind of thinking over encapsulation as a philosophical stance. Am I the only one thinking like this? -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Fri, 30 Aug 2013 23:07:47 -0700, Fabrice Pombet wrote: well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. Incorrect. You have not changed the type or value of any object. a is not an object, it is a *name*, and while you can change the object bound to the name, the objects remain unchanged. When you do this: x = 23 x = 42 the *object* 23 does not change, only the name binding changes. To do otherwise would cause all sorts of surprises: # THIS DOES NOT HAPPEN IN PYTHON # or any other language, as far as I am aware x = 23 y = x # y now has the value 23 x = 42 # change the value of the object ### NOT SO! ### print y = prints 42 Name binding (assignment) does not change objects. It changes the link between a name and the object, but the object remains untouched (unless it is unbound, and garbage collected). Assignment is not mutation. Assigning to a name does not modify the object that was previously bound. But even if you were right about changing the type and value of objects in place -- Python allows you to mutate lists and dicts in place, and even mutate the type of some objects, although not built-ins -- your understanding is still confused. Re-assignment (re-binding) of local variables is hardly a violation of encapsulation. But if it was, then Java and C++ have no encapsulation either, because you can re-assign to local variables inside a function too. If you want to see a language without encapsulation, you need to look at something like 1970s-style BASIC, a language where all variables are global, where there is no support for grouping related code into separate modules or files, where the closest thing to a function call is GOTO or GOSUB. Of course, languages can have *more* or *less* encapsulation than other languages. C lets you encapsulate related functions into a file, but it has no way of grouping data and functions together except loosely, in a file. C++ adds classes, which has more encapsulation since you can group functions and their data together. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? Of course you could. All you need is a way to tell the compiler not to type-check the variable a. Or more practically, some way to declare variable a as a reference to an untyped or generic value. C# has the dynamic keyword for this functionality. I don't know about Java or C++, but the JVM is certainly capable of implementing dynamic typing as there are various dynamically-typed languages built on top of the JVM, such as OpenXION and Cobra. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 8/31/13 7:46 AM, Steven D'Aprano wrote: On Fri, 30 Aug 2013 23:07:47 -0700, Fabrice Pombet wrote: well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. Incorrect. You have not changed the type or value of any object. a is not an object, it is a *name*, and while you can change the object bound to the name, the objects remain unchanged. When you do this: x = 23 x = 42 the *object* 23 does not change, only the name binding changes. To do otherwise would cause all sorts of surprises: # THIS DOES NOT HAPPEN IN PYTHON # or any other language, as far as I am aware x = 23 y = x # y now has the value 23 x = 42 # change the value of the object ### NOT SO! ### print y = prints 42 Name binding (assignment) does not change objects. It changes the link between a name and the object, but the object remains untouched (unless it is unbound, and garbage collected). Assignment is not mutation. Assigning to a name does not modify the object that was previously bound. I wrote a piece about names and values that might help clarify these points: Facts and Myths about Names and Values in Python: http://nedbatchelder.com/text/names.html --Ned. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
http://nedbatchelder.com/text/names.html --Ned. This is an excellent explanation, thank you. It is mostly of theoretical interest though, and in practice, I still contend that the consequences towards the syntax are (or seem, if you prefer) analogous to those of the lack of encapsulation. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 31, 2013 1:46:52 PM UTC+2, Steven D'Aprano wrote: On Fri, 30 Aug 2013 23:07:47 -0700, Fabrice Pombet wrote: well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. Incorrect. You have not changed the type or value of any object. a is not an object, it is a *name*, and while you can change the object bound to the name, the objects remain unchanged. When you do this: x = 23 x = 42 the *object* 23 does not change, only the name binding changes. To do otherwise would cause all sorts of surprises: # THIS DOES NOT HAPPEN IN PYTHON # or any other language, as far as I am aware x = 23 y = x # y now has the value 23 x = 42 # change the value of the object ### NOT SO! ### print y = prints 42 Name binding (assignment) does not change objects. It changes the link between a name and the object, but the object remains untouched (unless it is unbound, and garbage collected). Assignment is not mutation. Assigning to a name does not modify the object that was previously bound. But even if you were right about changing the type and value of objects in place -- Python allows you to mutate lists and dicts in place, and even mutate the type of some objects, although not built-ins -- your understanding is still confused. Re-assignment (re-binding) of local variables is hardly a violation of encapsulation. But if it was, then Java and C++ have no encapsulation either, because you can re-assign to local variables inside a function too. If you want to see a language without encapsulation, you need to look at something like 1970s-style BASIC, a language where all variables are global, where there is no support for grouping related code into separate modules or files, where the closest thing to a function call is GOTO or GOSUB. Of course, languages can have *more* or *less* encapsulation than other languages. C lets you encapsulate related functions into a file, but it has no way of grouping data and functions together except loosely, in a file. C++ adds classes, which has more encapsulation since you can group functions and their data together. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? Of course you could. All you need is a way to tell the compiler not to type-check the variable a. Or more practically, some way to declare variable a as a reference to an untyped or generic value. C# has the dynamic keyword for this functionality. I don't know about Java or C++, but the JVM is certainly capable of implementing dynamic typing as there are various dynamically-typed languages built on top of the JVM, such as OpenXION and Cobra. -- Steven Steve, I think that your definition of encapsulation is too wide to give a reasonable answer to the question at hand. If I understand you correctly, you are taking encapsulation as a language characteristic, rather than a principle. Plus, you seem to forget that encapsulation is an OOP principle, and, forgive me if I am wrong, does not apply normally to functions or languages like C. Please read Steve Holden's (in chaz') definition, and tell us whether you think that Python enforces strongly this principle, I think that would be a good basis for an agreement. My answer is no, it doesn't, but it allows you to abide by it if you want to. Unlike Java or C++ who would tend to do exactly the contrary (enforces it strictly, and (possibly?) allow you to discard it at times with a few jiffies (or not? I don't know)) -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 1 September 2013 03:31, Dennis Lee Bieber wlfr...@ix.netcom.com wrote: On Fri, 30 Aug 2013 23:07:47 -0700 (PDT), Fabrice Pombet fp2...@gmail.com declaimed the following: well, look at that: a=(1,2) a=2+3 -a is an object and I have changed its type and value from outside. As far as I am concerned this is one hell of an encapsulation violation... Could you do this -strictly speaking- in Java or C++? There is where your major misunderstanding is... a is a NAME attached (bound) to an object. In the first statement, the object is the tuple (1,2). That object was not changed when you execute the second statement -- which is taking two integer objects and creating a new integer object having a value of '5', and then attaches the NAME a to the new object. If no other names are bound to the (1,2) object, it will be garbage collected. I'll try another way to explain it, using Java terminology(since Fabrice appears to be familiar with Java). Object a = Arrays.asList(1, 2); // a is a reference to the ListInteger returned by Arrays.asList a = Integer.valueOf(2 + 3); // a is now a reference to the Integer returned by Integer.valueOf You have not changed the type of 'a' in any way - you have simply changed what the name 'a' refers to. This is functionally identical to your Python code above,except that in Python you do not have to downcast the Object reference 'a' or use reflection to call methods on it or access it's members (think of it as Python does reflection automatically for you). Tim Delaney -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 17, 2013 2:26:32 PM UTC+2, Fernando Saldanha wrote: I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. Questions: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Fernando, it is widely accepted that Python pays very little attention to encapsulation as a principle set in stone. Chaz's definition of encapsulation is also mine. Now you need to consider that taking this principle off the hostel of OOP does not mean that you can do whatever you fancy and you can't make anything unsettable. There are plenty of techniques within Python that allow you to protect your arguments (in particular, decorators) inside a Class. Now, lets get to the pretentious philosophical discussion: I guess encapsulation is quite the opposite of, say, dynamic typing, which is arguably core in Python. In practice this allows Python to be less verbose: at the end of the day, if you look back at your previous languages, don't you find that some of their compulsory features are usually more of a pain than something useful in practice? And after all, whither encapsulation? Can't we just have objects whose arguments are determined externally if we want to? And that is the ballgame: as my old tutor says: the claptrap of setters and getters does not need to be here if it is unnecessary. I would add: so long as you can have them when you deem it necessary, and Python allows that. -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Fri, 30 Aug 2013 10:43:28 -0700, Fabrice Pombet wrote: On Saturday, August 17, 2013 2:26:32 PM UTC+2, Fernando Saldanha wrote: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Fernando, it is widely accepted that Python pays very little attention to encapsulation as a principle set in stone. Widely accepted by whom? Python code is *full* of encapsulation. Functions, methods, classes, modules, packages, even local variables, are all mechanisms for encapsulating code and data. Those who say that Python has little or no encapsulation are talking rubbish. Chaz's definition of encapsulation is also mine. Who is Chaz, and what definition does he have? Now you need to consider that taking this principle off the hostel of OOP does not mean that you can do whatever you fancy and you can't make anything unsettable. There are plenty of techniques within Python that allow you to protect your arguments (in particular, decorators) inside a Class. And now you are talking about information hiding and protection, which is not the same of encapsulation, no matter what the academics think. Sometimes the air gets a bit too thin to breathe way up at the top of those ivory towers... Encapsulation is about grouping code that needs to be together together. In contract, you have programming languages that give you little, or nothing, in the way of grouping -- everything is one big chunk of code, with GOTO or GOSUB to jump from place to place. Functions and procedures are the first, most simple, form of encapsulation. Classes allow you to encapsulate multiple functions (methods) together with the data they need to operate on in one chunk. Even in C++ or Java, you can have classes that provide no information hiding at all -- just declare everything public. On the other hand, non-OOP languages like C can implement information hiding. In C, you can hide information from other files by declaring them as static. Variables declared inside a brace-delimited block only exist within that block: local variables are hidden. For example: int foo; static int bar; bar is hidden from other files. Likewise, in this function: int func(void) { int baz; ... } baz is local to func, and invisible to any other function. So you can have information hiding without classes, and classes without information hiding. The two concepts are obviously independent, but as usual, the academics who are in love with OOP like to pretend that anything that is of any interest whatsoever in computing was invented by Java and C++. There are even languages with functions, but no local variables. For instance, older versions of Forth let you define functions, what Forth calls words, but all functions operate on the same global stack. Python has excellent encapsulation: we can combine code that ought to be together into a function, related functions into a class, related classes into a module, and related modules into a package. Now, lets get to the pretentious philosophical discussion: I guess encapsulation is quite the opposite of, say, dynamic typing, which is arguably core in Python. They are utterly unrelated. Dynamic typing has nothing to do with whether or not you can encapsulate code into chunks (subroutines, functions, modules, classes...) or whether you have to write one big amorphous unstructured program where every chunk of code can reach inside other chunks of code. Nor does dynamic type have to do with information hiding. You can have a private member of a class regardless of whether that member has a single fixed type enforced at compile-time, or a dynamically typed value enforced at run-time. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Saturday, August 17, 2013 8:26:32 AM UTC-4, Fernando Saldanha wrote: I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. Questions: 1) Is there a good text where I can read about the language philosophy? What practices are pythonic or unpythonic? 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Thanks for any insights. FS Hi FS, I'm taking the Python Cert series w/ O'Reilly School of Technology, which I recommend if you've got a good handle on OO programming. In any event, according to what I've learned, encapsulation is the idea that the only way to access or change the data inside an object is by calling its methods. This idea has never really gained much ground in the Python world, and it is normally considered acceptable to both read and set an object's attributes from anywhere in a program. Not being an expert OO programmer, I take this at face value. There are ways to protect class attributes from having their values reset from outside. That is, they can be made internal use only and an AttributeError raised when someone tries to change the attribute(s). This involves __setattr__ and checking if the key of the attribute is in a/the list of attributes you've chose to protect. If so, raise AttributeError. Hope that helps in some small measure. In the interest of full disclosure, answering a Python question is part of my homework for the O'Reilly Python 4 class I'm taking. Good luck! -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Mon, Aug 19, 2013, at 3:05, Steven D'Aprano wrote: In this toy example, both parties are at fault: the author of Parrot for unnecessary data-hiding of something which is so obviously a useful piece of information and should be part of the public interface, It may wish to be notified when its name changes, and so have a name property. The subclass may want to use a variable called _name for some other purpose. (maybe name isn't the best example). Examples often look pathological when you simplify out the bit that makes them make sense. -- Random832 -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Aug 21, 2013 10:53 AM, random...@fastmail.us wrote: On Mon, Aug 19, 2013, at 3:05, Steven D'Aprano wrote: In this toy example, both parties are at fault: the author of Parrot for unnecessary data-hiding of something which is so obviously a useful piece of information and should be part of the public interface, It may wish to be notified when its name changes, and so have a name property. The example as given has no such property, and regardless of whether it is a property or an attribute the public API should just be called name. The subclass may want to use a variable called _name for some other purpose. (maybe name isn't the best example). Probably not a good idea for multiple reasons if the base class already has something called name. On Aug 21, 2013 10:53 AM, random...@fastmail.us wrote: On Mon, Aug 19, 2013, at 3:05, Steven D'Aprano wrote: In this toy example, both parties are at fault: the author of Parrot for unnecessary data-hiding of something which is so obviously a useful piece of information and should be part of the public interface, It may wish to be notified when its name changes, and so have a name property. The subclass may want to use a variable called _name for some other purpose. (maybe name isn't the best example). Examples often look pathological when you simplify out the bit that makes them make sense. -- Random832 -- http://mail.python.org/mailman/listinfo/python-list -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Wed, 21 Aug 2013 12:52:06 -0400, random832 wrote: On Mon, Aug 19, 2013, at 3:05, Steven D'Aprano wrote: In this toy example, both parties are at fault: the author of Parrot for unnecessary data-hiding of something which is so obviously a useful piece of information and should be part of the public interface, It may wish to be notified when its name changes, and so have a name property. The subclass may want to use a variable called _name for some other purpose. (maybe name isn't the best example). Such a name property would be a public interface, and so a Good Thing. However, my toy example was of a case where something *obviously useful* was being left out of the public interface. If it were a public property, it wouldn't be the case that it were left out, would it? Examples often look pathological when you simplify out the bit that makes them make sense. Naturally :-) I did call this a toy example. Nevertheless, in the Real World, data hiding can sometimes be a bit of a religion. Not all cases where people try various tricks and hacks to gain access to private and protected members are specious. The whole Java getter and setter philosophy is based on the idea that everything, even the most innocuous data attribute, ought to be private, with a computed getter and setter Just In Case some day in the future you want to wrap access in code. In Python, you can turn an attribute into a computed property with no change to the public interface. In Java, you can't. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sun, 18 Aug 2013 18:15:10 +0100, Joshua Landau wrote: On 17 August 2013 17:17, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Sat, 17 Aug 2013 05:26:32 -0700, fsaldan1 wrote: how do I deal with the fact that other programmers can easily alter the values of members of my classes? ... If they insist on messing with your private single-underscore _attributes, you can't stop them, but that's okay, you don't have to be sympathetic when they shoot their foot off. Just slap them with a large halibut[1] and laugh. I know I've cropped your points but I just want to mention here that the only reason to monkey-patch code in these ways where you'd want to stop them is when the alternative is *worse*. It's like removing railings from a cliff to stop people hitting the bars. I'm not actually talking about monkey-patching. I'm talking about just normal inheritance of classes. E.g. If a module has this class: class Parrot: def __init__(self): self._name = Polly def talk(self): print %s wants a cracker! % self._name I might be tempted to do this: class MyParrot: def __init__(self): super(MyParrot, self).__init__() self._name = George No monkey-patching involved. But, if the author of Parrot class changes his implementation and gets rid of _name, or even makes it public name, my subclass will stop working. Sucks to be me. In this toy example, both parties are at fault: the author of Parrot for unnecessary data-hiding of something which is so obviously a useful piece of information and should be part of the public interface, and me for nevertheless ignoring that warning and using the private attribute in my own code. More realistic examples may be different. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 17 August 2013 17:17, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote: On Sat, 17 Aug 2013 05:26:32 -0700, fsaldan1 wrote: how do I deal with the fact that other programmers can easily alter the values of members of my classes? ... If they insist on messing with your private single-underscore _attributes, you can't stop them, but that's okay, you don't have to be sympathetic when they shoot their foot off. Just slap them with a large halibut[1] and laugh. I know I've cropped your points but I just want to mention here that the only reason to monkey-patch code in these ways where you'd want to stop them is when the alternative is *worse*. It's like removing railings from a cliff to stop people hitting the bars. -- http://mail.python.org/mailman/listinfo/python-list
Encapsulation unpythonic?
I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. Questions: 1) Is there a good text where I can read about the language philosophy? What practices are pythonic or unpythonic? 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Thanks for any insights. FS -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
In Guido's own words: We're all consenting adults here. http://importthis.tumblr.com/post/6719643315/public-private-attributes Skip -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 17 August 2013 22:26, fsald...@gmail.com wrote: 1) Is there a good text where I can read about the language philosophy? What practices are pythonic or unpythonic? 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Try this: http://dirtsimple.org/2004/12/python-is-not-java.html -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sat, Aug 17, 2013 at 1:26 PM, fsald...@gmail.com wrote: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Very simply: You accept it. Let them! It's their responsibility. Python scripts are generally assumed to start at the beginning, go on till they reach the end, then stop (like the White King's advice to Alice). The author of the application is assumed to be in command of everything. If s/he chooses to monkey-patch something, so be it. If that monkey-patch breaks in the next version, it's the app author's problem. As a module or class author, you just need to make sure you don't make crazy changes to the environment, and all will be well. If you have invariants that you want to maintain, you can simply document the one official way to mutate your objects (use the .foo() method, don't tinker with the members), and most people will respect that. But most of the time, that's not even an issue - all you have to do is tell yourself It's fine for them to change stuff, and (a) you save the hassle of preventing them, and (b) you save the hassle of writing tons of boilerplate to grant specific access. class Point def __init__(self,x,y): self.x,self.y=x,y def distance(self,other): return math.sqrt((self.x-other.x)**2+(self.y-other.y)**2) foo = Point(0,0) while True: foo.x+=deltax; foo.y+=deltay if foo.distance(bar)50: break Easy! No getter/setter needed. ChrisA -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sat, 17 Aug 2013 05:26:32 -0700, fsaldan1 wrote: I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. Utter nonsense. Whoever told you this doesn't understand what encapsulation is. Python encapsulates related code into objects. It encapsulates related objects into modules. It encapsulates related modules into packages. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. That's *data hiding*, not encapsulation. Very few languages -- possibly none at all -- can hide data from a sufficiently motivated programmer. Python doesn't even try. We're all adults here is the philosophy, and data hiding is by convention, not enforced by the compiler. Single leading underscores are private. Don't touch them. If you do, and code breaks, nobody will give you sympathy. You have nobody to blame but yourself. Double leading underscores are private, and also have name-mangling to try to avoid certain inheritance-related issues. In general, it's more of a nuisance than anything else, so most people don't bother. Consider double underscore __names to be for advanced OOP usage, 98% of the time a single underscore is enough. Double leading and trailing __names__ are reserved for Python. They're not necessarily private, but if you're calling them directly, you're probably doing something wrong. Again, consider them to be advanced usage. Questions: 1) Is there a good text where I can read about the language philosophy? What practices are pythonic or unpythonic? Good question! Start at the interactive interpreter: import this This is a reasonable description of what it means to be Pythonic: http://blog.startifact.com/posts/older/what-is-pythonic.html This is a good pair of resources, comparing the Java and Python philosophies, and the strengths of each: http://dirtsimple.org/2004/12/python-is-not-java.html http://dirtsimple.org/2004/12/java-is-not-python-either.html Also, it helps to understand that Python is named after Monty Python, not the snake. It's not necessary to like anarchic British humour, but it helps to get some of the references. We'll talk about spam, ham, eggs rather than foo, bar, baz, and the Cheeseshop, and the Spanish Inquisition, and Norwegian Blue parrots. But ultimately, writing Pythonic code doesn't come from reading a list of rules. It comes from becoming comfortable with the language, from understanding its strengths and weaknesses, from reading lots of people's code, and writing lots of code, and learning the idioms. 2) If it is in fact true that encapsulation is rarely used, Not true. It is true that data hiding is really used though, at least in pure-Python code, except by convention. (C extensions are much more strict about data hiding, since you can crash the compiler if you muck about with C-level internals. Exceptions are a good thing. Segfaults are not.) how do I deal with the fact that other programmers can easily alter the values of members of my classes? Embrace it! That's a good thing! In Java or C++ or other languages, other programmers are going to alter your classes' members anyway. The only difference is that they will spend hours or days fighting the compiler in order to do so, and eventually end up with horrible, fragile, non-portable code. Besides, while it's nearly always a Bad Thing to mess with private attributes, sometimes it is a really, really Useful Thing to *inspect* private attributes, for debugging. Python makes that easy. Treat other programmers as adults, and they in turn will treat you the same way. If they insist on messing with your private single-underscore _attributes, you can't stop them, but that's okay, you don't have to be sympathetic when they shoot their foot off. Just slap them with a large halibut[1] and laugh. [1] Another Monty Python reference. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 08/17/2013 05:26 AM, fsald...@gmail.com wrote: I am new to Python, with experience in Java, C++ and R. As I understand encapsulation is not a big thing in the Python world. I read that you can put two underscores before the name of a variable within a class declaration but in the many examples of code I looked at this is not widely used. I also read that encapsulation is unpythonic. Questions: 1) Is there a good text where I can read about the language philosophy? What practices are pythonic or unpythonic? 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Thanks for any insights. FS You are confusing encapsulation with data hiding! Encapsulation is very much a part of Python. Every class, module, indeed every object, encapsulates some kind of behavior. However, *hiding* the members of a class is not considered Pythonic. There is no private/public as in C++, however, there are way to achieve that effect. Gary Herron -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On 8/17/2013 11:50 AM, Chris Angelico wrote: On Sat, Aug 17, 2013 at 1:26 PM, fsald...@gmail.com wrote: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Very simply: You accept it. Let them! It's their responsibility. When a project has multiple programmers, there is a possibility that module C could monkeypatch module A in a way that breaks existing user module B. But it is still the collective responsibility of the respective users or project manager to assign responsibility for fixing the conflict. -- Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Encapsulation unpythonic?
On Sat, Aug 17, 2013 at 10:22 PM, Terry Reedy tjre...@udel.edu wrote: On 8/17/2013 11:50 AM, Chris Angelico wrote: On Sat, Aug 17, 2013 at 1:26 PM, fsald...@gmail.com wrote: 2) If it is in fact true that encapsulation is rarely used, how do I deal with the fact that other programmers can easily alter the values of members of my classes? Very simply: You accept it. Let them! It's their responsibility. When a project has multiple programmers, there is a possibility that module C could monkeypatch module A in a way that breaks existing user module B. But it is still the collective responsibility of the respective users or project manager to assign responsibility for fixing the conflict. Yep. I would say there that the responsibility is with module C's programmers; they are the ones breaching encapsulation, ergo it's primarily their responsibility to both test this (against current usage) and thoroughly document it (against future changes). Personally, I would like to see a comment in module A that says something like NOTE: This {function|attribute|spam} is replaced externally under [some circumstance]. Changes to its purpose may affect Module B. to make it clear what's going on. At that point, of course, it stops being monkeypatching and becomes documented and official behaviour, so maybe that's not really an argument in this example. ChrisA -- http://mail.python.org/mailman/listinfo/python-list