mystilleef wrote: > Bruno Desthuilliers wrote: > >>mystilleef wrote: >> (snip) >>>> >>>>>I have used that name in >>>>>dozens of places spanning over 27000 LOC. >>>> >>>>Too bad for you. >>> >>> >>>Thank you, that was helpful. >> >>What am I supposed to say ? You choose a bad name for a public symbol, >>used it in 27000 lines of Python code (which certainly took some time to >>write), > > > This is a __baseless__ statement.
Please explain what's wrong ? The "bad naming" part is your own statement, the "27000 lines" is your own statement too, and I don't see what's wrong with the assumption that producing 27000 lines of Python took some time. > For all you know I could have used > the attribute twice in those 27000 lines of code. How does this make my statement wrong ? Did I imply that you used this attribute in each and any of the 27000 lines ? > Even then searching > for and replacing the attribute is tedious and error prone. Indeed, and whether you believe it or not, I do share your pain here. I had to face similar problem, and without even find and grep (a dumb 'CASE Tool' that stored it's proprietary language code in a non-documented binary format and was missing decent, reliable search/replace utilities). And the project was actually more than 50KLOC, forms description excluded. > >>and all of a sudden you realize the name is bad and proceed to >>fix the problem. > > Yes, the same way many programmers suddenly realize their class, > function, method, project, etc is poorly designed even after using it > for months and proceed to fix the problem. Shit happens. Agreed. I don't pretend to be better than anyone else at this. > >>If you know of any other way than a massive >>find/replace, please share. > > > I wouldn't have started the topic if I did. Apparently the only > solution is to rereference the attribute with a better name and pray > and hope third party developers will use the better name. Or search and > replace! Is actually this code already published ? If yes, you have the option of making the 'tmp' accessor a computed attribute pointing to the better named one, have the hidden getter/setter code emit a warning (including useful informations about where the attributes is accessed - this is opened to inspection), and officialy deprecate the badly named attribute so you can definitively get rid of it in a near release. > >>But blaming the language for your error won't help. > > I did no such thing, you are making that up. Sorry, that's what I understood. If it's me being guilty of overreaction, please accept my apologies. > >>>>>There's a chance that other >>>>>develops might misinterpret exactly what "tmp" does. Plus I don't want >>>>>emails from other developers querying me about what "tmp" is/does. >>>>>"tmp" is obvious to me, but not necessarily to others. >>>> >>>>So why did you name it that way at first ? >>>> >>> >>>What does it matter? There are 10 million and one reasons from given >>>identifiers bad names. >> >>And how many reasons to use a bad name in 27000 LOCs before deciding to >>fix the problem ? >> > > Do you really think I used the name 27000 times in 27000 lines of code? Of course not. But since 27KLOC is far from trivial for a Python application, one can think that you had time to notice something wrong with the naming/use of this attribute. > Maybe I'm not making myself clear. Having to search 27000 lines of code > to replace an identifier name is tedious and error prone. Yes. You can of course encapsulate access to the attribute in a property and have that property either emit a warning, raise an exception, log the access etc, so if you missed some use of it, chances are you'll find out pretty soon. Unit tests may help too - they can be great for reporting broken code. You may also want to look if lint-like tools (pylint etc) can help you there. > >>>>>Now compare that >>>>>to the accessors. >>>> >>>>But 'tmp' actually *is* an accessor. >>> >>> >>>I didn't say it wasn't. >> >>Yes you did. May I quote ? >>""" >>"tmp" is obvious to me, but not necessarily to others. Now compare that >>to the accessors. Not only do they improve readability at the expense >>of more code, they actually allow me to change the lousily named >>attribute "tmp" to "temporary_buffer" without grepping, seding, >>searching, replacing and praying. >>""" >> >>This obviously implies that you don't understand 'tmp' as being an accessor. >> > > You are quoting me out of context. I was speaking with respect to real > accessors, not Python's latent implementation mechanisms. This I had understood. My point is that if you *see* a public attribute name as really being an accessor with automagical default getters/setters (FWIW, look at the __getattribute__ method and Python's name lookup rules - you'll notice that it's really how it works), then your "compare that to accessors" doesn't stand. > >>>>>Not only do they improve readability >>>> >>>>Err... do you find: >>>> >>>>obj.set_temporary_buffer(val) >>>>val = obj.get_temporary_buffer() >>>> >>>>really more readable than: >>>> >>>>obj.temporary_buffer = val >>>>val = obj.temporary_buffer >>> >>> >>>I didn't name the attribute temporary_buffer, I named it tmp. >> >>You didn't name the *accessor* 'temporary_buffer', you named it 'tmp'. >>You are *exactly* in the same situation as if you had used getter/setter >>named "get_tmp" and 'set_tmp". And your point about getters/setters >>"improving readability" is moot. > > No I'm not. Naming attributes and naming methods are entirely different > situations. Why ? In Python, a "method" is nothing else than a descriptor (attribute) returning a callable. I agree that there's a small difference between a callable and a non-callable object, in that you can apply the __call__ operator only to callables, but this doesn't make such a difference here. In Python, methods are attributes. And naming is naming. > (snip) >> >>>In Java there's a clear distinction between attributes >>>and methods. >> >>Yes, and that's a big weakness of Java. But that's another point, and >>absolutely irrelevant here. Failing to understand a language semantics >>gives no right to complain about the language. >> > > I never complained about either languages. You are making that up. I may be misunderstanding your point about "Java having a clear distinction between attributes and methods" and overinterpreting it as implying "Python doesn't and it led me into a bad situation, hence Java is Good(tm) and Python is Bad(tm)". If so, once again, I do apologize. >>>>>Sure, if you are dealing with less >>>>>than a 1000LOC you can get away with using "tmp" or renaming it easily. >>>>>But if you are dealing with a much larger code base and more >>>>>developers, issues like this rapidly become a nuisance. >>>> >>>>Indeed. But it's *your* responsability to choose good names for the API.> >>> >>>I choose good names for most of my APIs. But there cases when you never >>>know an attribute will actually be an API before hand. >> >>Then don't make it part of the API. And anyway, 27000 lines of Python >>take some time to write, so you had the opportunity to address the >>problem long ago - FWIW, you could have fixed it as soon as you noticed >>you were accessing this attribute in client code. >> > > Yes, I fixed it then. Which was 27000 lines of code later. Not exactly a garden party. >>>>>Yes, it is possible to name crappy accessors too (e.g set_tmp/get_tmp). >>>> >>>>or 'tmp'. >>>> >>>>>But developers tend to pay more attention to given methods/functions >>>>>less crappy names, at least when compared to data attributes. >>>> >>>>s/developpers/you/> >>> >>>Ha, right! I bet you are perfect developer. >> >>Certainly not, but I wouldn't confuse my own problems with a general >>rule. Note FWIW that I wouldn't blame a language (or my lack of >>understanding of that language) for my own errors. >> > > Can you point me to exactly where I blamed Python for anything? Point addressed above. >>>>>This >>>>>stems from the fact that in many languages data attributes aren't >>>>>usually part of the API, >>>> >>>>Once again, in Python, there is *no* such thing as 'data attributes'. >>>>*All* attributes are *objects* - some of them callable. >>>> >>> >>>I didn't say attributes weren't objects. >> >>Nope, but you constantly bring that false "data/method" dichotomy in >>your justifications for having badly named a public symbol. > > There is a dichotomy between data and methods. Yes even in Python. The only dichotomy, from a technical POV, is that methods are callable - but so are classes, and any object that has a '__call__' attribute that is itself a callable. The 'dichotomy' here is the same as the dichotomy between iterable and non iterable objects. Of between file-like and non-file like objects. IOW, the difference amounts to supported interface, not to the very nature of the concerned objects. >>>>>I know I would not name the accessors set_tmp/get_tmp, because my >>>>>philosophy is that methods/functions need to have meaningful names and >>>>>state their intended purpose. >>>> >>>>That's true for each and every name in a program. >>>> >>>> >>>> >>>>>I don't hold data attributes to such >>>>>standards >>>> >>>>Too bad for you. >>>> >>>Thank you. >> >>For what ? You "don't hold data attributes to such standard". As a >>consequence (and as a result of not having addressed the problem >>sooner), you end up fixing 27000 lines of code. Too bad for you then. >>Some would haved learned from the mistake, which then would have turned >>into experience. Seems more and more obvious that you prefer to come >>whining here instead and blaming the language for your own errors. Too >>bad for you again. >> > > That's just silly. Yes, agreed. My fault. Let's take it back and not start fighting because of a misunderstanding. (snip) >>>>>and I imagine many developers don't either and least based on >>>>>other people's code I've read. Plus there are many occassions when >>>>>attributes are not intended to be APIs, >>>> >>>>Then mark them as being implementation (ie : prefix them with a single >>>>underscore). >>> >>>I thought that too was unpythonic. >> >>It's a well-known convention, as you would have noticed if you had read >>some existing python code, read PEP8, or just looked/asked for Python >>naming conventions. FWIW, that's one of the first thing I learned with >>Python. >> > > I know. Many people still think the private/public classification is > unpythonic. I'd rather say that many people thinks that language-enforced access restrictors and the "public methods/private data" scheme are unpythonic. And that if you're not sure wether a given name should be API or implementation then make it part of the API - but then choose a meaningful name for it !-) >>>>>but eventually become one. >>>>>After all most data attributes are created with the purpose of serving >>>>>methods. >>>> >>>>Nope. You have the class API, and the class implementation. Both made of >>>>both callable and non-callable attributes. >>>> >>> >>>Or objects have state and behavior. Data attributes represent state and >>>methods represent behavior. >> >>Is a getter "behaviour" ? If yes, how does this differ from public >>"data" attributes from a semantic POV ? >> > Yes, a getter is a behavior. It instructs the object to perform an > action. All methods are message channels to an object. Ok. Python's name lookup all go thru the __getattribute__ accessor. So obj.value is a synonym for obj.__getattribute__('value') which, according to your definition, is behaviour. Hence, there's *no* "data attribute" in Python. > A data attribute > does not perform any action. It just holds data for an object. The attribute itself may not perform any action, but looking up the name is an action. > Even > though methods are attributes, attributes aren't necessarily methods. Indeed. > This is basic OO, I don't see anything semantically complex about it. It becomes complex when the languages sees functions as first-order objects supporting the Callable interfaces and let you define your own callable objects, and sees attribute-access as call to an hidden (well, not that much hidden) getter/setter mechanism that one as all lattitude to customize in many ways. Seeing that way really takes you out of the Java semantic/mindset (well, at least it did to me, and I guess for at least a few others). >>>I'm not new to Python >>>either. >> >>New enough to not understand how Python's object model, semantic and >>overall philosophy strongly differs from Java/C++. >> > > This isn't an issue about object models and semantics, this is a > design/architecture issue with regards to eliminating the chances of > errors in large source code. I was talking about the way you IMHO try to force-fit the common "private data/public method" scheme (and it's associated dichotomy between data and functions) into Python. Of course callable and non-callable attributes usually have different usages, but we're really far from the Java model where's the dichotomy between "data" and "code" is irremediable. Now wrt/ your naming problem, I think that you would not have done the mistake if you had apply has much care to the naming of a non-callable attribute as you assert (and I don't doubt you on this) you would have for a callable one. You explain that you failed to do so because of you viewing "data attributes" (ie non-callable attributes) as fundamentally different from "methods" (ie callable attributes), so I try to share the POV that Python is really different here, hoping this will help you detect similar errors sooner. >>>>If you intented 'tmp' to be part of the API, then you're responsible for >>>>the bad naming. >>> >>>I never intended it to be part of the API. >> >>So you should not have used it outside the class. >> > The fact that I did, means I should have. Then if you felt it finally had to be part of the API *and* was badly named, you should have renamed it immediatly. But granted, it's easier to say so afterward than to make the right choice in the moment. > >>>It evolved to be an >>>important part of the system. >> >>Then you had plenty of occasions to address the problem. >> > > And how did you come up with that? By understanding "evolved" as a process (implying a timeline), and "important part of the system" as widely used. (snip fighting part) >>>I only just noticed because I was trying to implement >>>a plug-in system and I needed to expose an important class. I would not >>>have considered the issue a problem without this requirement. Except >>>you are a prophet, you sometimes can't know before hand how certain >>>classes will end up being used especially if requirements suddenly >>>change. >> >>Yes, that's something I'm well aware of. And that's why I pay attention >>to naming and to interface/implementation separation. >> > > Good for you. That doesn't mean I get it right. (snip, idem) -- bruno desthuilliers python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for p in '[EMAIL PROTECTED]'.split('@')])" -- http://mail.python.org/mailman/listinfo/python-list