Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #16967 > unrolled thread
| Started by | Roy Smith <roy@panix.com> |
|---|---|
| First post | 2011-12-10 15:47 -0500 |
| Last post | 2011-12-13 10:15 +0100 |
| Articles | 7 on this page of 27 — 12 participants |
Back to article view | Back to comp.lang.python
Overriding a global Roy Smith <roy@panix.com> - 2011-12-10 15:47 -0500
Re: Overriding a global MRAB <python@mrabarnett.plus.com> - 2011-12-10 21:07 +0000
Re: Overriding a global Roy Smith <roy@panix.com> - 2011-12-10 16:10 -0500
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-12 12:13 +0100
Re: Overriding a global Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-12 21:28 +0000
Re: Overriding a global Dave Angel <d@davea.name> - 2011-12-12 16:43 -0500
Re: Overriding a global Ben Finney <ben+python@benfinney.id.au> - 2011-12-13 09:27 +1100
Re: Overriding a global Dave Angel <d@davea.name> - 2011-12-12 20:46 -0500
Re: Overriding a global Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-13 01:48 +0000
Re: Overriding a global Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-12 22:50 -0700
Re: Overriding a global Joshua Landau <joshua.landau.ws@gmail.com> - 2011-12-13 08:34 +0000
Re: Overriding a global Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-13 12:34 -0700
Re: Overriding a global Ian Kelly <ian.g.kelly@gmail.com> - 2011-12-13 12:54 -0700
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-13 10:54 +0100
Re: Overriding a global Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-13 11:15 +0000
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-13 14:30 +0100
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-14 11:14 +0100
Re: Overriding a global Chris Angelico <rosuav@gmail.com> - 2011-12-14 21:32 +1100
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-14 13:05 +0100
Re: Overriding a global Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-14 12:53 +0000
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-14 14:35 +0100
Re: Overriding a global Chris Angelico <rosuav@gmail.com> - 2011-12-14 23:21 +1100
Re: Overriding a global Jean-Michel Pichavant <jeanmichel@sequans.com> - 2011-12-14 18:06 +0100
Re: Overriding a global Terry Reedy <tjreedy@udel.edu> - 2011-12-10 19:14 -0500
Re: Overriding a global Terry Reedy <tjreedy@udel.edu> - 2011-12-10 19:19 -0500
Re: Overriding a global Peter Otten <__peter__@web.de> - 2011-12-11 09:14 +0100
Re: Overriding a global Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2011-12-13 10:15 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | Jean-Michel Pichavant <jeanmichel@sequans.com> |
|---|---|
| Date | 2011-12-14 14:35 +0100 |
| Message-ID | <mailman.3642.1323869724.27778.python-list@python.org> |
| In reply to | #17207 |
Steven D'Aprano wrote: > On Wed, 14 Dec 2011 13:05:19 +0100, Jean-Michel Pichavant wrote: > > >> Bad ideas : >> >> i = 5 >> >> def spam(): >> for i,v in enumerate([1,2,3,4]): >> for i,v in enumerate(['a','b', 'c']): >> print i, v >> print i,v # bad surprise >> > > The bad surprise happens because you are using the same name twice in > *one* namespace, the local scope. This example has nothing to do with > local/global name clashes: the existence of global i is irrelevant. > Python's scoping rules work correctly, and global i is not affected by > the local i. > > Programming languages use multiple namespaces so that you don't need to > make your variable names globally unique. There are languages that don't > distinguish between local and global. Python is not one of them. The > programmer should feel free to use local names without worrying too much > if they accidentally use a global name. > > Having said that, re-using names isn't *entirely* risk free, because if > you use a global name locally, and then try to *also* access the global > name, you will fail. This is called shadowing, and the problem with > shadowing is when you do it by accident. (Newbies are particularly prone > to this, especially when they call variables "str", "list", etc.) But it > is the "by accident" part that is dangerous: there is nothing wrong with > shadowing globals or builtins when you do it by design. > > > >> good ideas : >> >> # global >> nameThatWillNotBeUsedlocally = 'foo' >> > > Oh please. Names can be too long as well as too short. > > > >> def spam(): >> for qtyIndex, quantity in enumerate([5,6,3,1]): >> for fruitIndex, fruit in enumerate(['orange', 'banana']): >> print fruitIndex, fruit >> print qtyIndex, quantity >> > > More sensible naming conventions are to be encouraged, but verbose names > just for the sake of verbosity is not. spam() is a five line function; if > the programmer can't keep track of the meaning of loop variables i and j > over five lines, perhaps they should consider a change of career and get > a job more suited to their intellectual prowess. I hear McDonalds is > hiring. > > If spam() were larger and more complex, then more expressive names would > be valuable. But in the simple example you give, it just adds noise. > > The next time I'll illustrate meaningful names, I'll write a 3000 lines function, just to be sure no one states that my point does'nt apply to a function named spam which only counts from 1 to 3. And don't answer that the spam function above does not count from 1 to 3, I know it doesn't. For anyone interested in the actual topic, a good reading is http://tottinge.blogsome.com/meaningfulnames/#Mult_Meanings JM
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-12-14 23:21 +1100 |
| Message-ID | <mailman.3639.1323865292.27778.python-list@python.org> |
| In reply to | #17123 |
On Wed, Dec 14, 2011 at 11:05 PM, Jean-Michel Pichavant
<jeanmichel@sequans.com> wrote:
> Chris Angelico wrote:
>>
>> So... it's a bad idea for me to use 'i' many times in my code, with
>> the same name having different meanings in different places? In
>> languages with infinitely-nesting scopes...
> Bad ideas :
>
> i = 5
>
> def spam():
> for i,v in enumerate([1,2,3,4]):
> for i,v in enumerate(['a','b', 'c']):
> print i, v
> print i,v # bad surprise
That's my point. It's not safe to do it in Python, because the "inner"
local i is the same as the "outer" local i. Python doesn't have block
scope the way most C-like languages do.
int spam()
{
for (int i=0;i<5;++i)
{
for (int i=2;i<4;++i) write("inner "+i+"\n");
write("outer "+i+"\n");
}
}
Works perfectly, and the only cost is that variables must be formally declared.
In Python, you can kinda fudge that sort of thing with nested functions.
def spam():
q=2 # just to prove that the scopes really are nested
for i in range(5):
def ham():
for i in range(2,4):
print("q = %d, i = %d"%(q,i))
ham()
print("i = %d"%i)
It's somewhat clunky, but it does give the illusion of block scope.
Inners mask outers, outers are visible to inner functions. It's an odd
construct though. Very odd.
So... I think I've figured out how to implement from __future__ import braces.
#define { def innerfunc():
#define } innerfunc()
And there you are, out of your difficulty at once!
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Jean-Michel Pichavant <jeanmichel@sequans.com> |
|---|---|
| Date | 2011-12-14 18:06 +0100 |
| Message-ID | <mailman.3651.1323882381.27778.python-list@python.org> |
| In reply to | #17123 |
Joshua Landau wrote:
> [snip]
> Using currentLogger is just padding, in my opinion. *Every *value is
> "current<value>".
Not always. I try to keep names on the same object because that object
is supposed to be named that way.
I can change one of the object attribute, but the object named that way
keep being the same.
Class Foo:
self.__init__(self):
self.banana = 5
myFoo = Foo()
Now there's a slight difference between
myFoo = Exception()
and
myFoo.banana = 4
The first statement rebind myFoo to something complitely different.
the second statement change one of the object rightfully named myFoo ..
attribute (not sure about this construct :D )
Int being inmutable, you can rebind a name without changing its meaning.
>
> In regards to a second name - yes this could work and in many cases
> would be desirable, but it doesn't really help this circumstance.
> [assume, for a moment, a lot of functions used a local logger]
> "localLogger" would tell you very little about what the logger
> actually /is/. You still have to look that up. [end assumption]
> Additionally, this would make changing a logger that uses the default
> to a local one /much/ harder. And don't say "but you can just always
> make a local copy", as then you lose the advantage of a global.
>
> Typing something like "logger = childLogger(id)" to the start of a
> function call *is explicit*, it's clean, and it makes sense to have a
> default that's global. You're not appending cruft ("current") and you
> have consistency. If you added "logger = globalLogger" to every
> function start as well you can argue that it's better. I agree it's
> more explicit. But then you lose unneeded if only a small portion of
> your code localises logger. But I would recommend it if a large
> portion of code used local variants.
>
> AND:
>
> The next time I'll illustrate meaningful names, I'll write a 3000
> lines function, just to be sure no one states that my point
> does'nt apply to a function named spam which only counts from 1 to 3.
> And don't answer that the spam function above does not count from
> 1 to 3, I know it doesn't.
>
>
> You're acting in sarcasm to a comment on scale, when you yourself said
> that one of my comments was invalid due to names that were scaled down
> for exampling. It seems a bit hypocritical to me. That said, not all
> functions are long. If the short ones use short names that's fine: I'm
> pretty sure you said it's not.
>
> And in regards to the link:
> 1) __add__ says otherwise (technically, the operator "+"). It's rarely
> confused me.
> 2) That's not what we're discussing. As it said: "As long as the
> parameter lists are semantically equal and the desired result is the
> same, all is well." They're doing semantically the same thing (to
> different log levels) with the same parameter lists and they're not
> class methods. You /could/ say that the semantics are different, but
> classes act in a context in the same way local variables can be
> thought of doing, and semantics are the same for them. Instead of a
> different self, it's a different log file/level. Same semantics.
I'd like to argue about that but I won't cause I have the feeling my
lack of ultra precise english would cause me more trouble. Note that I'm
not blaming anyone but me, no sarcasm inside.
JM
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2011-12-10 19:14 -0500 |
| Message-ID | <mailman.3504.1323562487.27778.python-list@python.org> |
| In reply to | #16967 |
On 12/10/2011 3:47 PM, Roy Smith wrote:
>
> What I really want to do is:
>
> def function(self):
Add a global statement to rebind a global name:
global logger
> logger = logger.getChild('function')
> logger.debug('stuff')
> logger.debug('other stuff')
>
> which lets me not have to change any lines of code other than inserting
> the one to redefine logger. Unfortunately, that's not legal Python (it
> leads to "UnboundLocalError: local variable 'logger' referenced before
> assignment").
>
> Any ideas on the best way to implement this?
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2011-12-10 19:19 -0500 |
| Message-ID | <mailman.3506.1323562796.27778.python-list@python.org> |
| In reply to | #16967 |
On 12/10/2011 7:14 PM, Terry Reedy wrote:
> On 12/10/2011 3:47 PM, Roy Smith wrote:
>>
>> What I really want to do is:
>>
>> def function(self):
>
> Add a global statement to rebind a global name:
> global logger
But I see that that is not what you want to do, which is to override the
global name just within the function while still accessing the global
name. MRAB's solution does that nicely.
>> logger = logger.getChild('function')
>> logger.debug('stuff')
>> logger.debug('other stuff')
>>
>> which lets me not have to change any lines of code other than inserting
>> the one to redefine logger. Unfortunately, that's not legal Python (it
>> leads to "UnboundLocalError: local variable 'logger' referenced before
>> assignment").
>>
>> Any ideas on the best way to implement this?
>
>
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2011-12-11 09:14 +0100 |
| Message-ID | <mailman.3508.1323591284.27778.python-list@python.org> |
| In reply to | #16967 |
Roy Smith wrote:
> I've got a code pattern I use a lot. In each module, I create a logger
> for the entire module and log to it all over:
>
> logger = logging.getLogger('my.module.name')
>
> class Foo:
> def function(self):
> logger.debug('stuff')
> logger.debug('other stuff')
>
> and so on. This works, but every once in a while I decide that a
> particular function needs a more specific logger, so I can adjust the
> logging level for that function independent of the rest of the module.
> What I really want to do is:
>
> def function(self):
> logger = logger.getChild('function')
> logger.debug('stuff')
> logger.debug('other stuff')
>
> which lets me not have to change any lines of code other than inserting
> the one to redefine logger. Unfortunately, that's not legal Python (it
> leads to "UnboundLocalError: local variable 'logger' referenced before
> assignment").
>
> Any ideas on the best way to implement this?
def function(self, logger=logger.getChild("function")):
logger.debug("stuff")
But the "best way" is to use another name.
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2011-12-13 10:15 +0100 |
| Message-ID | <mailman.3581.1323767811.27778.python-list@python.org> |
| In reply to | #16967 |
On 12/10/2011 09:47 PM, Roy Smith wrote:
> I've got a code pattern I use a lot. In each module, I create a logger
> for the entire module and log to it all over:
>
> logger = logging.getLogger('my.module.name')
>
> class Foo:
> def function(self):
> logger.debug('stuff')
> logger.debug('other stuff')
>
> and so on. This works, but every once in a while I decide that a
> particular function needs a more specific logger, so I can adjust the
> logging level for that function independent of the rest of the module.
> What I really want to do is:
>
> def function(self):
> logger = logger.getChild('function')
> logger.debug('stuff')
> logger.debug('other stuff')
>
> which lets me not have to change any lines of code other than inserting
> the one to redefine logger. Unfortunately, that's not legal Python (it
> leads to "UnboundLocalError: local variable 'logger' referenced before
> assignment").
>
> Any ideas on the best way to implement this?
>
How about two global references:
globallogger = logger = logging.getLogger('my.module.name')
def function(self):
logger = globallogger.getChild('function')
logger.debug('stuff')
logger.debug('other stuff')
--
Antoon Pardon
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.python
csiph-web