Re: Function to avoid a global variable

2020-05-01 Thread DL Neil via Python-list

On 2/05/20 12:00 PM, Bob van der Poel wrote:

I still think that the use of a keyword like "static" would be easiest.

def foo(arg):
 static counter = 0
 counter += 1
 if counter ...

And in this case static just means that it's a variable only readable
inside foo() and it should maintain it's value between calls. A "global"
without the name pollution. Or is this too simple  ???



No, it's not "too simple" an example/request.

Although they are often considered more complex than materials suitable 
for 'beginner' (?simple) training, generator functions (and 
async-gen-func-s) already offer this (without the static-statement)


def gen( args ):
counter = 0
while counter < max_depth:
yield counter

counter will retain its value ("maintain state") between iterations.
--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-05-01 Thread DL Neil via Python-list

On 2/05/20 11:30 AM, Chris Angelico wrote:

On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list
 wrote:


On 28/04/20 7:36 PM, Chris Angelico wrote:

"Best"? Not sure about that. Functions are first-class objects in
Python, so a function *is* a callable object. You don't have to create
a custom class with a call method just to be able to attach attributes
to your function.

ChrisA



Using a mutable object as a function default parameter value
and changing it inside the function looks like a "trick"
according to me.


Sure. But you're contrasting this to a suggestion to literally just
attach attributes to a function. Python lets you actually do that. You
don't have to simulate the feature by creating a custom class and
making it callable - you just straight-up add attributes to a
function. Sure, what you suggested works, but there's no reason to.



Functions are objects too! I regularly point-out this powerful facility,
and its affordances, but...


Yes, it's perfectly reasonable and even sensible to attach an attribute;
BUT do many people expect to find such? If we were to collectively
survey our own application code, how many examples would we find - as a
percentage of such a corpus?

Expectation: it would be v.v.low. Accordingly, whilst
perfectly-implemented Python, and thus not a "trick", at least it is
something that is easy for 'an ordinary person' to 'miss' (or
misunderstand).



One of the problems with the use of function attributes is that
there's no way to say "this function". You have to use its name.
Otherwise, it would be easy to write self-contained idioms such as
static variables or omitted arg detection without the risk of
polluting the namespace:

def some_function(x, y, z=object()):
 if z is me.__defaults__[0]:
 z = x + y
 ...

def static(**kw):
 def deco(f):
 for name, initial in kw.items():
 setattr(f, name, initial)
 return f
 return deco

@static(called=0)
def other_function():
 me.called += 1
 ...

Obviously the name "me" can't be used, as it'd break a bunch of code,
but conceptually this would be incredibly helpful. It'd also be a
reliable idiom for recursion optimization - any "me()" is guaranteed
to be recursion and may potentially give info to an optimizer.

Perhaps, if Python had a way to identify the current function, it
would feel less odd to attach attributes to it.


The trouble is, functions seem to have an existential crisis: they know 
their own __name__ but have no sense of self! However, all is not lost 
because they are still very __func__-y.

(apologies to anyone reading this whilst drinking)

Unfortunately, Shakespeare is not the only one to ask: what's in a name, 
Rosie?


>>> def double( x ):
... return x + x
...
>>> double( 2 )
4
>>> double.__name__
'double'

### so-far, so-good - but let's pick-up the pace:

>>> pasodoble = double
>>> pasodoble( 2 )
4
>>> pasodoble.__name__
'double'

### You're so tired (from working quickly, perhaps) that you can't even 
remember your own __name__?


(by extrapolation, I estimate; but you (@Chris) will no doubt, educate)
I'm assuming this has something to do with "decorators"?


In relation to the wider part of the problem-mentioned, a class is 
instantiated to become a second, and separate-but-linked, object. 
Whereas the two function-names are merely multiple labels to the same 
object (and id()):


>>> pasodoble

>>> double


### Whereas:-

>>> class C():
... '''Docstring that says nothing about a class that does just as 
much.'''

...
>>> c = C()
>>> C.__name__
'C'
>>> c.__name__
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'C' object has no attribute '__name__'

### Wait a minute! Have you forgotten your own name?
### What else don't you know?

>>> c.self
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'C' object has no attribute 'self'
>>> c.__doc__
'Docstring that says nothing about a class that does nothing.'

### (yes, I know, *I* caused the first of these two!)
### However, they are separate entities. Proof:

>>> id( C )
94619010560432
>>> id(c)
140014684436880

Hence, being empowered to accomplish a lot more with instantiated classes.

Although methods are merely functions, a method enjoys 'extra' by virtue 
of being an attribute of a class's instance and being able to call-upon 
further attributes within the same namespace.

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-05-01 Thread Bob van der Poel
I still think that the use of a keyword like "static" would be easiest.

def foo(arg):
static counter = 0
counter += 1
if counter ...

And in this case static just means that it's a variable only readable
inside foo() and it should maintain it's value between calls. A "global"
without the name pollution. Or is this too simple  ???


On Fri, May 1, 2020 at 4:30 PM Chris Angelico  wrote:

> On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list
>  wrote:
> >
> > On 28/04/20 7:36 PM, Chris Angelico wrote:
> > >>> "Best"? Not sure about that. Functions are first-class objects in
> > >>> Python, so a function *is* a callable object. You don't have to
> create
> > >>> a custom class with a call method just to be able to attach
> attributes
> > >>> to your function.
> > >>>
> > >>> ChrisA
> > >>>
> > >>
> > >> Using a mutable object as a function default parameter value
> > >> and changing it inside the function looks like a "trick"
> > >> according to me.
> > >
> > > Sure. But you're contrasting this to a suggestion to literally just
> > > attach attributes to a function. Python lets you actually do that. You
> > > don't have to simulate the feature by creating a custom class and
> > > making it callable - you just straight-up add attributes to a
> > > function. Sure, what you suggested works, but there's no reason to.
> >
> >
> > Functions are objects too! I regularly point-out this powerful facility,
> > and its affordances, but...
> >
> >
> > Yes, it's perfectly reasonable and even sensible to attach an attribute;
> > BUT do many people expect to find such? If we were to collectively
> > survey our own application code, how many examples would we find - as a
> > percentage of such a corpus?
> >
> > Expectation: it would be v.v.low. Accordingly, whilst
> > perfectly-implemented Python, and thus not a "trick", at least it is
> > something that is easy for 'an ordinary person' to 'miss' (or
> > misunderstand).
> >
>
> One of the problems with the use of function attributes is that
> there's no way to say "this function". You have to use its name.
> Otherwise, it would be easy to write self-contained idioms such as
> static variables or omitted arg detection without the risk of
> polluting the namespace:
>
> def some_function(x, y, z=object()):
> if z is me.__defaults__[0]:
> z = x + y
> ...
>
> def static(**kw):
> def deco(f):
> for name, initial in kw.items():
> setattr(f, name, initial)
> return f
> return deco
>
> @static(called=0)
> def other_function():
> me.called += 1
> ...
>
> Obviously the name "me" can't be used, as it'd break a bunch of code,
> but conceptually this would be incredibly helpful. It'd also be a
> reliable idiom for recursion optimization - any "me()" is guaranteed
> to be recursion and may potentially give info to an optimizer.
>
> Perhaps, if Python had a way to identify the current function, it
> would feel less odd to attach attributes to it.
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 

 Listen to my FREE CD at http://www.mellowood.ca/music/cedars 
Bob van der Poel ** Wynndel, British Columbia, CANADA **
EMAIL: b...@mellowood.ca
WWW:   http://www.mellowood.ca
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-05-01 Thread Chris Angelico
On Sat, May 2, 2020 at 9:14 AM DL Neil via Python-list
 wrote:
>
> On 28/04/20 7:36 PM, Chris Angelico wrote:
> >>> "Best"? Not sure about that. Functions are first-class objects in
> >>> Python, so a function *is* a callable object. You don't have to create
> >>> a custom class with a call method just to be able to attach attributes
> >>> to your function.
> >>>
> >>> ChrisA
> >>>
> >>
> >> Using a mutable object as a function default parameter value
> >> and changing it inside the function looks like a "trick"
> >> according to me.
> >
> > Sure. But you're contrasting this to a suggestion to literally just
> > attach attributes to a function. Python lets you actually do that. You
> > don't have to simulate the feature by creating a custom class and
> > making it callable - you just straight-up add attributes to a
> > function. Sure, what you suggested works, but there's no reason to.
>
>
> Functions are objects too! I regularly point-out this powerful facility,
> and its affordances, but...
>
>
> Yes, it's perfectly reasonable and even sensible to attach an attribute;
> BUT do many people expect to find such? If we were to collectively
> survey our own application code, how many examples would we find - as a
> percentage of such a corpus?
>
> Expectation: it would be v.v.low. Accordingly, whilst
> perfectly-implemented Python, and thus not a "trick", at least it is
> something that is easy for 'an ordinary person' to 'miss' (or
> misunderstand).
>

One of the problems with the use of function attributes is that
there's no way to say "this function". You have to use its name.
Otherwise, it would be easy to write self-contained idioms such as
static variables or omitted arg detection without the risk of
polluting the namespace:

def some_function(x, y, z=object()):
if z is me.__defaults__[0]:
z = x + y
...

def static(**kw):
def deco(f):
for name, initial in kw.items():
setattr(f, name, initial)
return f
return deco

@static(called=0)
def other_function():
me.called += 1
...

Obviously the name "me" can't be used, as it'd break a bunch of code,
but conceptually this would be incredibly helpful. It'd also be a
reliable idiom for recursion optimization - any "me()" is guaranteed
to be recursion and may potentially give info to an optimizer.

Perhaps, if Python had a way to identify the current function, it
would feel less odd to attach attributes to it.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-05-01 Thread DL Neil via Python-list

On 28/04/20 7:36 PM, Chris Angelico wrote:

"Best"? Not sure about that. Functions are first-class objects in
Python, so a function *is* a callable object. You don't have to create
a custom class with a call method just to be able to attach attributes
to your function.

ChrisA



Using a mutable object as a function default parameter value
and changing it inside the function looks like a "trick"
according to me.


Sure. But you're contrasting this to a suggestion to literally just
attach attributes to a function. Python lets you actually do that. You
don't have to simulate the feature by creating a custom class and
making it callable - you just straight-up add attributes to a
function. Sure, what you suggested works, but there's no reason to.



Functions are objects too! I regularly point-out this powerful facility, 
and its affordances, but...



Yes, it's perfectly reasonable and even sensible to attach an attribute; 
BUT do many people expect to find such? If we were to collectively 
survey our own application code, how many examples would we find - as a 
percentage of such a corpus?


Expectation: it would be v.v.low. Accordingly, whilst 
perfectly-implemented Python, and thus not a "trick", at least it is 
something that is easy for 'an ordinary person' to 'miss' (or 
misunderstand).


The same cognitive logic applies to function parameters. Use of these is 
laced with 'gotchas', because people assume a different logic to/fail to 
properly understand Python. Hence such style decisions as 'use None, or 
not at all'.


Personal opinion: I've never really liked closures, and have tended to 
associate them with other languages that actually need them in order to 
accomplish common-constructs or have them as a tenet/pillar of their 
language-design philosophy. Python does not, so...


The choice of global variable should not be completely discounted - we 
have been given the global statement for a reason! However, its use in 
this case has been rightly-criticised (elsewhere) as an unnecessary 
'pollution'.


Which leaves us (or me!) with the overly-wordy wrapping-in-a-class 
option. The use of a class-attribute seems natural and is a well-worn 
pattern often used for counting instances, totalling a value across 
instances, or indeed limiting (usually to one, single) instantiations.



Opinion: The function attribute is most efficient, in terms of 
programmer time or LoC. However the class-construct seems more-readily 
recognisable.


That said, the OP's stated specification is to limit the depth of a 
stack. Many would have implemented the stack as a (derived) class, and 
thus adding a class-attribute control-variable would become only part of 
a wider whole - rather than the class being created merely to replace a 
simpler and more-concise function.


Contrarily, if we (all) use function-attributes and enjoy the simplicity 
and power justifying the reasons they were given to us, they would 
become second-nature to code AND to read!

--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-29 Thread Tony Flury via Python-list


On 28/04/2020 06:49, jf...@ms4.hinet.net wrote:

bvdp於 2020年4月28日星期二 UTC+8上午9時46分35秒寫道:

Oh my, that is very cool! So, I can do this:

def foo(i):
 if not 'bar' in foo.__dict__:
 foo.bar = 5
 foo.bar += i

You can have function attribute created this way if you like:

 def foo(i):
 foo.bar += i
 foo.bar = 5

--Jach

And as you have shown - foo.bar is effectively a global variable - just 
one with a qualified name :-)



--

Tony Flury

--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread Christian Gollwitzer

Am 28.04.20 um 09:54 schrieb ast:

funny !

So we found 4 different ways to handle a memory in a function

1- Use a function parameter with a mutable default value

2- Use a function attribute

3- Use a callable object, and store your stuff inside an object attr

4- Use a closure to emulate a static function variable

Any more ?




5- Use a global variable, of course


That's definitely the least recommendable solution. Global variable 
names pollute the global namespace, therefore they don't make sense to 
just store state within one function. They should be reserved to the 
case where multiple functions access a common state. Usually it is best 
to restrict the scope of a variable to the region of code where it 
necessarily needs to be available.


Christian


--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread ast

Le 28/04/2020 à 09:52, ast a écrit :

Le 28/04/2020 à 09:39, Antoon Pardon a écrit :



Op 27/04/20 om 18:39 schreef Bob van der Poel:

Thanks Chris!

At least my code isn't (quite!) as bad as the xkcd example :)

Guess my "concern" is using the initialized array in the function:

    def myfunct(a, b, c=array[0,1,2,3] )

always feels like an abuse.

Has anyone seriously considered implementing  a true static variable 
in a

function? Is there a PEP?


You can emulate a static variable is with a closure.

def make_parseStack():

 depth = 0

 def parseStack(inc):
    nonlocal depth

 if depth > 50:
 ... report error and die nicely
 depth += inc

 return parseStack

parseStack = make_parseStack()



funny !

So we found 4 different ways to handle a memory in a function

1- Use a function parameter with a mutable default value

2- Use a function attribute

3- Use a callable object, and store your stuff inside an object attr

4- Use a closure to emulate a static function variable

Any more ?




5- Use a global variable, of course
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread ast

Le 28/04/2020 à 09:39, Antoon Pardon a écrit :



Op 27/04/20 om 18:39 schreef Bob van der Poel:

Thanks Chris!

At least my code isn't (quite!) as bad as the xkcd example :)

Guess my "concern" is using the initialized array in the function:

    def myfunct(a, b, c=array[0,1,2,3] )

always feels like an abuse.

Has anyone seriously considered implementing  a true static variable in a
function? Is there a PEP?


You can emulate a static variable is with a closure.

def make_parseStack():

     depth = 0

     def parseStack(inc):
    nonlocal depth

     if depth > 50:
     ... report error and die nicely
     depth += inc

     return parseStack

parseStack = make_parseStack()



funny !

So we found 4 different ways to handle a memory in a function

1- Use a function parameter with a mutable default value

2- Use a function attribute

3- Use a callable object, and store your stuff inside an object attr

4- Use a closure to emulate a static function variable

Any more ?


--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread Antoon Pardon




Op 27/04/20 om 18:39 schreef Bob van der Poel:

Thanks Chris!

At least my code isn't (quite!) as bad as the xkcd example :)

Guess my "concern" is using the initialized array in the function:

def myfunct(a, b, c=array[0,1,2,3] )

always feels like an abuse.

Has anyone seriously considered implementing  a true static variable in a
function? Is there a PEP?


You can emulate a static variable is with a closure.

def make_parseStack():

depth = 0

def parseStack(inc):
   nonlocal depth

if depth > 50:
... report error and die nicely
depth += inc

return parseStack

parseStack = make_parseStack()

--
Antoon Pardon.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread Chris Angelico
On Tue, Apr 28, 2020 at 5:26 PM ast  wrote:
>
> Le 28/04/2020 à 09:13, Chris Angelico a écrit :
> > On Tue, Apr 28, 2020 at 4:56 PM ast  wrote:
> >>
> >> Le 27/04/2020 à 04:46, Bob van der Poel a écrit :
>
>
> >
> > "Best"? Not sure about that. Functions are first-class objects in
> > Python, so a function *is* a callable object. You don't have to create
> > a custom class with a call method just to be able to attach attributes
> > to your function.
> >
> > ChrisA
> >
>
> Using a mutable object as a function default parameter value
> and changing it inside the function looks like a "trick"
> according to me.

Sure. But you're contrasting this to a suggestion to literally just
attach attributes to a function. Python lets you actually do that. You
don't have to simulate the feature by creating a custom class and
making it callable - you just straight-up add attributes to a
function. Sure, what you suggested works, but there's no reason to.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread ast

Le 28/04/2020 à 09:13, Chris Angelico a écrit :

On Tue, Apr 28, 2020 at 4:56 PM ast  wrote:


Le 27/04/2020 à 04:46, Bob van der Poel a écrit :





"Best"? Not sure about that. Functions are first-class objects in
Python, so a function *is* a callable object. You don't have to create
a custom class with a call method just to be able to attach attributes
to your function.

ChrisA



Using a mutable object as a function default parameter value
and changing it inside the function looks like a "trick"
according to me.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread Chris Angelico
On Tue, Apr 28, 2020 at 4:56 PM ast  wrote:
>
> Le 27/04/2020 à 04:46, Bob van der Poel a écrit :
> > Does this make as much sense as anything else? I need to track calls to a
> > function to make sure it doesn't get called to too great a depth. I had a
> > global which I inc/dec and then check in the function. Works fine, but I do
> > need to keep a global around just for this.
> >
> > So ... instead I wrote a short function:
> >
> >   def parseStack(inc, depth=[0]):
> >   if depth[0] > 50:
> >   ... report error and die nicely
> >  depth[0] += inc
> >
> > This gets rid of the global, and it moves my error check out of the main
> > code as well. But, I never feel all that great about using a list in the
> > function call for static storage.
> >
>
>
> Using a callable object is the best way to define a function
> with a memory
>
> class ParseStack:
>  def __init__(self):
>  self.depth=0
>  def __call__(self, inc, reset=True):
>  if reset:
>  self.depth = 0
>  if self.depth > 50:
>  ... report error
>  self.depth += 1
>  ... do your stuff
>
> parse_stack = ParseStack()
>
> and use "function" parse_stack
>
> parse_stack(43)

"Best"? Not sure about that. Functions are first-class objects in
Python, so a function *is* a callable object. You don't have to create
a custom class with a call method just to be able to attach attributes
to your function.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread ast

Le 28/04/2020 à 08:51, ast a écrit :

Le 27/04/2020 à 04:46, Bob van der Poel a écrit :

Does this make as much sense as anything else? I need to track calls to a
function to make sure it doesn't get called to too great a depth. I had a
global which I inc/dec and then check in the function. Works fine, but 
I do

need to keep a global around just for this.

So ... instead I wrote a short function:

  def parseStack(inc, depth=[0]):
  if depth[0] > 50:
  ... report error and die nicely
 depth[0] += inc

This gets rid of the global, and it moves my error check out of the main
code as well. But, I never feel all that great about using a list in the
function call for static storage.




Using a callable object is the best way to define a function
with a memory

class ParseStack:
     def __init__(self):
     self.depth=0
     def __call__(self, inc, reset=True):
     if reset:
     self.depth = 0
     if self.depth > 50:
     ... report error
     self.depth += 1
     ... do your stuff

parse_stack = ParseStack()

and use "function" parse_stack

parse_stack(43)
...



def __call__(self, inc, reset=False):
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-28 Thread ast

Le 27/04/2020 à 04:46, Bob van der Poel a écrit :

Does this make as much sense as anything else? I need to track calls to a
function to make sure it doesn't get called to too great a depth. I had a
global which I inc/dec and then check in the function. Works fine, but I do
need to keep a global around just for this.

So ... instead I wrote a short function:

  def parseStack(inc, depth=[0]):
  if depth[0] > 50:
  ... report error and die nicely
 depth[0] += inc

This gets rid of the global, and it moves my error check out of the main
code as well. But, I never feel all that great about using a list in the
function call for static storage.




Using a callable object is the best way to define a function
with a memory

class ParseStack:
def __init__(self):
self.depth=0
def __call__(self, inc, reset=True):
if reset:
self.depth = 0
if self.depth > 50:
... report error
self.depth += 1
... do your stuff

parse_stack = ParseStack()

and use "function" parse_stack

parse_stack(43)
...
--
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-27 Thread jfong
bvdp於 2020年4月28日星期二 UTC+8上午9時46分35秒寫道:
> Oh my, that is very cool! So, I can do this:
> 
> def foo(i):
> if not 'bar' in foo.__dict__:
> foo.bar = 5
> foo.bar += i

You can have function attribute created this way if you like:

def foo(i):
foo.bar += i
foo.bar = 5

--Jach

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-27 Thread Bob van der Poel
Oh my, that is very cool! So, I can do this:

def foo(i):
if not 'bar' in foo.__dict__:
foo.bar = 5
foo.bar += i

for a in range(10):
foo(1)
print (foo.bar)

Thanks. I will have to play more with this.



On Mon, Apr 27, 2020 at 5:31 PM Michael Torrie  wrote:

> On 4/27/20 10:39 AM, Bob van der Poel wrote:
> > Thanks Chris!
> >
> > At least my code isn't (quite!) as bad as the xkcd example :)
> >
> > Guess my "concern" is using the initialized array in the function:
> >
> >def myfunct(a, b, c=array[0,1,2,3] )
> >
> > always feels like an abuse.
> >
> > Has anyone seriously considered implementing  a true static variable in a
> > function? Is there a PEP?
>
> There's actually no need. You can create attributes on the function
> itself, just like a regular object:
>
> def foo():
> if not 'bar' in foo.__dict__:
> foo.bar = 5
>
> print (foo.bar)
>
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 

 Listen to my FREE CD at http://www.mellowood.ca/music/cedars 
Bob van der Poel ** Wynndel, British Columbia, CANADA **
EMAIL: b...@mellowood.ca
WWW:   http://www.mellowood.ca
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-27 Thread Michael Torrie
On 4/27/20 10:39 AM, Bob van der Poel wrote:
> Thanks Chris!
> 
> At least my code isn't (quite!) as bad as the xkcd example :)
> 
> Guess my "concern" is using the initialized array in the function:
> 
>def myfunct(a, b, c=array[0,1,2,3] )
> 
> always feels like an abuse.
> 
> Has anyone seriously considered implementing  a true static variable in a
> function? Is there a PEP?

There's actually no need. You can create attributes on the function
itself, just like a regular object:

def foo():
if not 'bar' in foo.__dict__:
foo.bar = 5

print (foo.bar)


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-27 Thread Bob van der Poel
Thanks Chris!

At least my code isn't (quite!) as bad as the xkcd example :)

Guess my "concern" is using the initialized array in the function:

   def myfunct(a, b, c=array[0,1,2,3] )

always feels like an abuse.

Has anyone seriously considered implementing  a true static variable in a
function? Is there a PEP?

Best,

On Sun, Apr 26, 2020 at 8:47 PM Chris Angelico  wrote:

> On Mon, Apr 27, 2020 at 1:39 PM Bob van der Poel  wrote:
> >
> > Does this make as much sense as anything else? I need to track calls to a
> > function to make sure it doesn't get called to too great a depth. I had a
> > global which I inc/dec and then check in the function. Works fine, but I
> do
> > need to keep a global around just for this.
> >
> > So ... instead I wrote a short function:
> >
> >  def parseStack(inc, depth=[0]):
> >  if depth[0] > 50:
> >  ... report error and die nicely
> > depth[0] += inc
> >
> > This gets rid of the global, and it moves my error check out of the main
> > code as well. But, I never feel all that great about using a list in the
> > function call for static storage.
>
> That's not really any different from a global. If globals bother you,
> this should as well. But it's also reasonable to NOT be bothered by it
> - it's not that big a problem.
>
> If this is directly recursive (if there's a call to parseStack inside
> parseStack itself, as opposed to being mutually recursive with one or
> more other functions), the easiest way to avoid the global is to just
> pass the parameter down - something like this:
>
> def spaminate(x, y, depth=0):
> ...
> spaminate(newx, newy, depth+1)
> ...
>
> But that can be harder if you have other things happening, eg if your
> function calls something else, which calls something else, which calls
> your function again. If it's that complex, I would just accept the
> global, honestly - globals (module-level variables) aren't the worst
> thing that can happen. You won't end up with code reviews like
> https://xkcd.com/1513/ just because of one global (or if you do, you
> REALLY need to find better code reviewers!).
>
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 

 Listen to my FREE CD at http://www.mellowood.ca/music/cedars 
Bob van der Poel ** Wynndel, British Columbia, CANADA **
EMAIL: b...@mellowood.ca
WWW:   http://www.mellowood.ca
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to avoid a global variable

2020-04-26 Thread Chris Angelico
On Mon, Apr 27, 2020 at 1:39 PM Bob van der Poel  wrote:
>
> Does this make as much sense as anything else? I need to track calls to a
> function to make sure it doesn't get called to too great a depth. I had a
> global which I inc/dec and then check in the function. Works fine, but I do
> need to keep a global around just for this.
>
> So ... instead I wrote a short function:
>
>  def parseStack(inc, depth=[0]):
>  if depth[0] > 50:
>  ... report error and die nicely
> depth[0] += inc
>
> This gets rid of the global, and it moves my error check out of the main
> code as well. But, I never feel all that great about using a list in the
> function call for static storage.

That's not really any different from a global. If globals bother you,
this should as well. But it's also reasonable to NOT be bothered by it
- it's not that big a problem.

If this is directly recursive (if there's a call to parseStack inside
parseStack itself, as opposed to being mutually recursive with one or
more other functions), the easiest way to avoid the global is to just
pass the parameter down - something like this:

def spaminate(x, y, depth=0):
...
spaminate(newx, newy, depth+1)
...

But that can be harder if you have other things happening, eg if your
function calls something else, which calls something else, which calls
your function again. If it's that complex, I would just accept the
global, honestly - globals (module-level variables) aren't the worst
thing that can happen. You won't end up with code reviews like
https://xkcd.com/1513/ just because of one global (or if you do, you
REALLY need to find better code reviewers!).

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Function to avoid a global variable

2020-04-26 Thread Bob van der Poel
Does this make as much sense as anything else? I need to track calls to a
function to make sure it doesn't get called to too great a depth. I had a
global which I inc/dec and then check in the function. Works fine, but I do
need to keep a global around just for this.

So ... instead I wrote a short function:

 def parseStack(inc, depth=[0]):
 if depth[0] > 50:
 ... report error and die nicely
depth[0] += inc

This gets rid of the global, and it moves my error check out of the main
code as well. But, I never feel all that great about using a list in the
function call for static storage.
-- 
https://mail.python.org/mailman/listinfo/python-list