aleaxit at yahoo.com
Tue Sep 5 14:40:37 CEST 2000
"Jonadab the Unsightly One" <jonadab at bright.net> wrote in message
news:39b456f2.62129230 at news.bright.net...
> "Alex Martelli" <alex at magenta.com> wrote:
> > You're thinking of 'variables' as reasonably-persistent names
> > for *locations in storage* -- a la C. Not a good mental model
> > for Python's variables...
> So, anyway, how flexible is Python's typeing?
It's pretty strict, but entirely carried by *objects*, never
by *names*. All a 'name' does is act as a label, or, maybe
better, a 'post-it', since it can most easily be "peeled off"
any object and (just-as-temporarily) bound to any other. The
"items" in a list or dictionary work just the same way as
'names' (as they should, since names are pretty transparently
just keys to items in some dictionary:-), as do the arguments
to functions and the values they return.
Most everything you'll care about is an object (and thus
can be named, appended to a list, placed in a dictionary,
passed as an argument, returned as a function's result):
numbers, strings, functions, classes, modules, methods
(either unbound or bound), instances, lists, dictionaries,
and quite a few other things.
This regularity, generality, and lack of special-casing, tends
to be the hallmark of Python (there are a few exceptions, but,
few indeed). No magic things happening behind the scenes,
such as numbers morphing into strings or vice versa (number
types _can_ 'morph' this way -- the term is 'coercion' -- and
you can write instances with morphing-ability, by having a
specially-named method in their class); no dirtying up the
language in the abused name of "convenience" (well, _almost_
no dirtying-up; not even Python is perfect -- just close:-).
The callOrPrint function you mention in passing is easy, e.g.:
although of course the "return something()" can fail at
runtime if 'something', while bound to something callable
(a function, method, class, or instance having a __call__
method, for example), is not callable *without arguments*.
But, if need be, you can do more 'introspection' (aka
'reflection'), and find out more about the object than
just whether it's callable or not. Python excels at this
(it's so inebriating and liberating that it's easy to go
overboard and forget one doesn't normally HAVE to do any
such analysis -- it's there for the time in a hundred it
may really be useful...!-).
Alternatively (often a useful paradigm!) you can wrap
any attempted actions in a try/except/else block, rather
than doing all of the previous querying to find out if
the actions are allowable. E.g., rough-and-ready...:
You're not *supposed* to use "except:" without a specific
list of exceptions that you expect and can handle, and
in production code it would be very unwise to do so, but,
in a toy case such as this, it's real handy -- call the
argument if it can correctly be called without args; if
the call is not acceptable, or terminates with any
exception, then print the argument. Easy-peasy...
More information about the Python-list