Scope and program structure problems
bruno.42.desthuilliers at websiteburo.invalid
Tue Jul 1 17:18:16 CEST 2008
John Dann a écrit :
> Many thanks for the repsonse - much appreciated.
> And sorry - yes I was probably compounding two separate issues here -
> the GUI one and the variable scope one. Maybe the wxPython list would
> be the best place to ask more about the GUI side of things.
> Then actually I can simplify my remaining question quite a lot - I
> know you've partly answered this already but let me just rephrase
> It must be commonplace to first use a variable or object
What difference do you make between a variable and an object in this
> within one
> function in a module and then want to use it again - perhaps still
> with the same value
For which definition of "same value" ? Remember, Python has *no*
primitive types. Everything is an object.
> as in the first function - in a second function.
> So what's the recommended Python way round this?
This is way too general to give a single straight answer - whatever the
language FWIW. Are both function in the same module ? Are they methods
of a same object ? Is the first function calling the second or are they
totally unrelated ?
> If I was using .Net
> then I'd be declaring the variables/objects explicitly
I personnally find the assignment, import, class and def statements (all
having a binding behaviour) to be rather explicit.
> and could set
> their scope according to how/where they were declared.
Names bound at the top-level are globals to the module. Names bound
within a function (including arguments) are locals, unless there has
been a global statement for them before in the same function's body.
Names bound within a class statement lives in the class's namespace (IOW
: they become class attributes, shared by all instances). And names
bound as object attributes (using either obj.name = whatever or
setattr(obj, "name", whatever)) become, well, object attributes.
Now there may be a couple points worth paying attention to :
1/ some types (numerics, strings and tuples at least) are immutable.
When doing :
i = 1
i = 2
the second assignment doesnt mutate the integer object bound to i, but
rebinds i to another integer object.
2/ the scope of a name isn't necessarily related to the scope of the
object bound to that name.
As an example, function's parameters *names* are local to the function,
but the actual arguments - the objects passed when calling the function
- are not.
IOW, rebinding a parameter name withing a function body will rebind the
name locally, but will not affect the object originally bound to that
name. But *mutating* an object passed as argument *will* (off course)
affect the object outside the function.
> But if the
> Python way is not to declare vars before use
For which definition of "var" and "use" ? Did you really try to use a
name that didn't exist in the accessible namespace - I mean, "use" for
anything else than binding ?
The first binding of a name in a namespace *is* the 'declaration'. If a
name is not defined in the currently accessible namespace, and you try
to do anything else than binding it, you'll get an exception.
> then this must create
> some problems for cross-function use.
If what you mean is that it makes it harder to litter you code with true
global variables, then it's obviously a *very* good thing IMHO !-)
But no, there's no more problem with shared state in Python than in any
other (imperative) language I know - usually less in fact since there's
no "application global" namespace. Most of the time, the appropriate way
to share state is to use classes - heck, that's what they were created
for, isn't it ?-). Sharing state thru module-level variables is ok as
long you only access it for reading (pseudo-constants etc).
Sometimes, it's ok to use a module-level variable read-write, but this
should be restricted to this particular module's implementation stuff
(IOW : the name is not part of the API, and only functions / methods in
this same module access it), and never done without a clear enough
understanding of Python's namespaces and bindings.
> So it is best to declare such vars at the module level (ie outside of
> a function) and set eg to Null/None or to assign them with a keyword
> such as global or static (assuming that concept applies in Python)
> at first use inside a function or what?
Usually, when you really need a module-level variable to be shared
read-write between functions, it happens that you can bind it to a
sensible default. Now what is a "sensible default" depends on the
concrete use case. Anyway, by all means, explicitely bind this name at
the top-level, before any code accessing it, and if possible with a
comment about this name being shared read/write by functions x and y.
My 2 cents...
More information about the Python-list