Google Groups unterstützt keine neuen Usenet-Beiträge oder ‑Abos mehr. Bisherige Inhalte sind weiterhin sichtbar.

function parameter: question about scope

0 Aufrufe
Direkt zur ersten ungelesenen Nachricht

Uwe Mayer

ungelesen,
14.07.2002, 21:06:5714.07.02
an
hi,

I've got a object method which works similar to the __deepcopy__()
function of the copy/deepcopy protocol. this function takes an optional
argument "memo={}":

def getElements(self, types, memo={}):
'''Returns a list of sub-elements.'''
if memo.has_key(id(self)): return memo[id(self)]
elements = super(Compound, self).getElements(types, memo)
if (types == ()) or (self.__class__ in types): elements.extend
([self])
return elements


This function checks wether self.__class__ is contained in 'types' and
if so, it adds itself to the list 'elements' and returns it.

The problem is, that 'memo' seems to live beyond method invocation - and
I don't know why:
If I call 'getElements( types=() )', the method works fine. The first
call to 'getElements( types=(<someClass>) )' works fine, too. The
parameter 'memo' seems to have remembered <someClass>, because when I
call 'getElements( types=() )' again I get the same result as in the
previous call which is different to the first call.

Calling 'getElements( types=(), memo={} )' works fine.

Why does 'memo' keep exising?

Thanks in advance
Uwe

Emile van Sebille

ungelesen,
14.07.2002, 12:14:0814.07.02
an
Uwe Mayer

> def getElements(self, types, memo={}):
[snip]

> The problem is, that 'memo' seems to live beyond method invocation -
and
> I don't know why:

When you use:

def getElements(self, types, memo={}):

memo will only be created once when the module is initially imported.
All subsequent access to getElements() that don't specifically override
memo share the same originally created copy of memo. You probably want
to do:

def getElements(self, types, memo=None):
if memo == None:
memo = {}

Then each invocation of getElements not passing in memo will get a newly
created memo.

HTH,

--

Emile van Sebille
em...@fenx.com

---------

Alex Martelli

ungelesen,
14.07.2002, 12:40:0914.07.02
an
Uwe Mayer wrote:

> hi,
>
> I've got a object method which works similar to the __deepcopy__()
> function of the copy/deepcopy protocol. this function takes an optional
> argument "memo={}":
>
> def getElements(self, types, memo={}):

...


> Why does 'memo' keep exising?

What "keeps existing" is the DEFAULT value of memo -- it keeps
existing because it's stored among the function's attributes.

That's how default values of arguments behave: constructed once,
when you execute statement def, and thereafter remembered as
long as the function object survives.

This is generally OK when the default value is immutable, and
almost never what you want when it's mutable. Solution: don't
use mutable objects as default values for arguments. E.g., change
your function's start into:

def getElements(self, types, memo=None):
if memo is None: memo = {}
# proceed as before


This is the most idiomatic Python approach.


Alex


0 neue Nachrichten