Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: however, considering what import a.module.that.is.quite.nested as myModule Won't work since I get the objects at run time myModule = __import__('whatever.module.imported.at.run.time', globals(), locals(), [], -1) See http://docs.python.org/library/functions.html#__import__ JM -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: Nope. it's nothing to do with imports. It's about objects passed to methods at run time. Complicated objects with many levels. Not about modules at all. Who is providing these objects ? - Your code ? = as said before, you can fix your design with a proper object model - 3rd party libraries ? = I'd be curious to know which one, because they usually do a good job providing a clean minimal public interface. However, do not redesign anything to get only shorter names. You can easily live with that, the way you're doing it is up to you and suggestions have been given. But keep in mind that you should'nt have got nested names that long in the first pace, no matter how complicated the internal implementation. JM -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. [snip] 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) [snip] -- Gerald Britton This is not solved by style but by design. You simply don't use too much nested objects. That's a sign of something wrong in your overall object model. Since I do not encounter this problem as often as you are, I guess it is a matter of habbits. however, considering what import a.module.that.is.quite.nested as myModule is doing, I guess using a local variable to store your nested method is just fine. JM -- http://mail.python.org/mailman/listinfo/python-list
Style question: Nicknames for deeply nested objects
Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Now, consider two scenarios: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) 2. You call it inside a loop: for item in some_iterable: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) For one thing, I find the long lines unattractive at best and error-prone at worst, especially if I also have some.other.deeply.nested.object.method that I might confuse with the first. To make it look better I might do this: _o = some.deeply.nested.object _o.method(_o.value) which is fine, I suppose. Then, putting on my company hat, I remembered that, from VBA, you could do this: with some.deeply.nested.object .method(.value) end with I like the structure of this, since the subordinate block can be indented, which makes it stand out. Also, it avoids temporary variables. So, I was thinking of how to get close to this in Python. I came up with two approaches: 1. _o = some.deeply.nested.object if 1: _o.method(_o.value) The if 1: forces me to indent the subordinate code, which sets it apart from the surrounding code. Note that I cannot just indent because I feel like it since Python is persnickety about indentation. 2. for _o in [some.deeply.nested.object]: _o.method(_o.value) The for... sets up the iterator and forces me to indent the subordinate code. As an aside, approach 1 generates less byte-code since approach 2 sets up loop machinery which you don't really need in this case. I have a couple of questions: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? 2. What other techniques have you used in such a situation? -- Gerald Britton -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 11:51 am, Gerald Britton gerald.brit...@gmail.com wrote: [...] that I might confuse with the first. To make it look better I might do this: _o = some.deeply.nested.object _o.method(_o.value) which is fine, I suppose. It is very fine. And you supposed correctly! Then, putting on my company hat, I remembered that, from VBA, you could do this: with some.deeply.nested.object .method(.value) end with I like the structure of this, since the subordinate block can be indented, which makes it stand out. Also, it avoids temporary variables. Yes it is a good idea! Well forgetting the horrendous VBA syntax this is. I brought this up many moons back as a feature request: Local Blocks. Here is how a pythonic local block would look with this as localvar: localvar.do_something() So, I was thinking of how to get close to this in Python. I came up with two approaches: 1. _o = some.deeply.nested.object if 1: _o.method(_o.value) bad idea! 2. for _o in [some.deeply.nested.object]: _o.method(_o.value) even worse idea! I have a couple of questions: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? neither! Stick with the original. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
In article mailman.1469.1296409883.6505.python-l...@python.org, Gerald Britton gerald.brit...@gmail.com wrote: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) I would probably turn that into: object = some.deeply.nested.object object.method(object.value1) object.method(object.value2) object.method(object.value3) i.e. make the temporary variable have the exact same name as the last component of the deeply nested thing you're trying to refactor. If the scope of use is small and the meaning is obvious from context, sometimes I'll shorten the name, i.e. obj = some.deeply.nested.object or even o = some.deeply.nested.object but I tend to avoid doing that. I'd rather be a little more verbose in preference to being a little more cryptic. -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 9:51 AM, Gerald Britton wrote: 1. If you had to choose between approaches 1 and 2, which one would you go for, and why? Neither. Ideally, I'd tweak the API around so the deeply nested structure isn't something I need to access regularly. But! If you can't do that, I'd do something like: --- start from contextlib import contextmanager class Item(object): pass deeply = Item() deeply.nested = Item() deeply.nested.thing = Item() @contextmanager def my(thing): yield thing with my(deeply.nested.thing) as o: o.hello = 1 print deeply.nested.thing.hello --- end That's a dummy context-manager which basically does nothing: it just abuses the context manager protocol to basically make a local variable and indent its usage. Its really just a run-around and slightly less efficient to do: _o = some.deeply.nested.object _o.method(_o.value) But with the whitespace added on. Personally, I'd usually just make a local variable and skip any tricks. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 12:23 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: --- start from contextlib import contextmanager class Item(object): pass deeply = Item() deeply.nested = Item() deeply.nested.thing = Item() @contextmanager def my(thing): yield thing with my(deeply.nested.thing) as o: o.hello = 1 print deeply.nested.thing.hello --- end Well congratulations Stephen, you win the obfuscation prize of the year! -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 10:35 AM, rantingrick wrote: Well congratulations Stephen, you win the obfuscation prize of the year! Yes, On 1/30/11 10:09 AM, rantingrick wrote: Here is how a pythonic local block would look with this as localvar: localvar.do_something() verses with my(this) as localvar: localvar.do_something() Is dreadfully more, er, obfuscated. I mean someone would have to know what the 'my' function does to understand what's going on! OH MY GOD. How can someone be expected to understand what a function does! Be serious! You can't expect that of them. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 30/01/2011 17:51, Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Now, consider two scenarios: 1. You need to call this thing many times with different arguments, so you wind up with: x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1) y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2) z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3) Neither. You should tell. Don't ask if you can avoid it. Compare... queen.getButter() and queen.dairymaid.alderney.getButter() see http://www.timelessteacherstuff.com/readerstheater/KingsBreakfast.pdf king doesn't care where or how the butter is brought. Neither should your code! What are you doing with value1, value2 and value3 when you have them anyway? Stuffing them 3 levels deep into something else? Stop writing procedural code, and write object oriented code instead! If you you make some tell deeply.nested.object about other.deeply.nested.object it can fetch its own values, but it might be better to have some tell other.deeply.nested.object about deeply.nested.object to it can issue the correct commands. Then you tell some to do Somthing by writing some.takeMeaningfullAction() and it all happens under the covers. Regards Ian -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: On 1/30/11 10:35 AM, rantingrick wrote: Well congratulations Stephen, you win the obfuscation prize of the year! Yes, On 1/30/11 10:09 AM, rantingrick wrote: Here is how a pythonic local block would look with this as localvar: localvar.do_something() verses with my(this) as localvar: localvar.do_something() Is dreadfully more, er, obfuscated. Absolutely! I mean someone would have to know what the 'my' function does to understand what's going on! Yes, and also how decorators word and generators work, and ... OH MY GOD. How can someone be expected to understand what a function does! Yes, and also how decorators word and generators work, and ... Be serious! You can't expect that of them. I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! But Stephen's 10 lines of somewhat obscure code actually works, and your two lines of code doesn't. I know which one I would prefer. -- Jerry -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On Sun, 30 Jan 2011 12:51:20 -0500, Gerald Britton wrote: Hi all, Today I was thinking about a problem I often encounter. Say that I have (seems I often do!) a deeply nested object, by which I mean object within object with object, etc. For example: x = some.deeply.nested.object.method (some.other.deeply.nested.object.value) Well, that's extreme but I've worked with code approaching that level of nested-ness. Then you're probably living in a state of sin, programming-wise, and you should stop doing that! You are violating the Law of Demeter. One dot, good. Two, acceptable. Three is a code smell. Four is a code reek. The Law of Demeter (more of a guideline than a law, really) says: If you want to get your dog to walk, call the dog. Don't talk to its legs, it confuses the dog and doesn't get it anywhere. http://en.wikipedia.org/wiki/Law_of_Demeter Another analogy: if you have to pay the paperboy for delivering the newspaper, you don't let him reach into your pocket, take out your wallet, open the wallet, take out whatever money he feels like, and put the wallet back. http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper- boy/demeter.pdf Despite my comment above, the Law of Demeter is not *really* a dot- counting exercise, although that's a handy short-cut for detecting potential problems. It can also apply to other data structures. If you've every seen C or Pascal code where you have a pointer to a pointer to a pointer to a pointer to a pointer to a pointer to some data, you've seen a violation. Consider your example: some.other.deeply.nested.object.value This is very tightly coupled code: the caller, who knows about the object `some`, needs to know the internal details of not just `some` but also `other`, `deeply`, `nested`, and `object`. As a basic principle, this is poor design! Which would you rather deal with? car.start() car.ignition.turn(key).connect(car.starter(battery), car.spark_plug) In particular, using temporary variables merely disguises the problem: temp = some.other temp = temp.deeply.nested x = temp.object.value Even though you never use more than two dots, you still have tight coupling. The point of Demeter is not to save dots (they're a renewable resource) but to reduce tight coupling. -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Style question: Nicknames for deeply nested objects
On 1/30/11 1:13 PM, rantingrick wrote: On Jan 30, 12:53 pm, Stephen Hansen me+list/pyt...@ixokai.io wrote: OH MY GOD. How can someone be expected to understand what a function does! Yes, and also how decorators word and generators work, and ... Be serious! You can't expect that of them. I don't. I don't expect anyone to write 10 lines of obfuscation code when just two will suffice. Maybe you should join the perl group as they would proud! Riiight. suffice doesn't mean what you think it means. Generally, if something suffices -- it actually, you know, ... works. My four lines of setup can get put into a library and treated as a recipe if they don't want to get into understanding generators or decorators: then its two lines to use, and those two lines are exactly like your two lines except for two little details: 1. They add a function call to the syntax. 2. They actually work. The OP doesn't have to understand decorators or generators if he doesn't want to: though I encourage him to do so, as they are beautiful and elegant tools that can very clearly and concisely help solve a lot of problems. Now, me? I wouldn't use the recipe, as I originally said in my response. I'd just use a local variable. But the OP didn't like that, and he wanted some indenting and whitespace to clearly demarcate where he intended to use the local. So I gave him a way to do that. You gave him... uh, what was it again? Oh, right. Nothing. As usual. -- Stephen Hansen ... Also: Ixokai ... Mail: me+list/python (AT) ixokai (DOT) io ... Blog: http://meh.ixokai.io/ signature.asc Description: OpenPGP digital signature -- http://mail.python.org/mailman/listinfo/python-list