From: wheres pythonmonks on
I think of an upcast as casting to the base-class (casting up the
inheritance tree).
http://en.wiktionary.org/wiki/upcast
But really, what I am thinking of doing is overriding the virtual
methods of a derived class with the base class behavior in an object
that I can then pass into methods that are base/derived agnostic.

defaultdict is the way to go.

W

<ps>
<rant>

Sadly, there are guidelines that I program by that are perhaps anti-pythonic:

1. Don't use "extra" variables in code. Don't use global variables.
Keep the scopes of local variables at a minimum to reduce state (the
exception being for inner loops) or variables explicitly identified as
part of the algorithm before implementation. [In python, just about
everything is a variable which is terrifying to me. I never want the
Alabama version of math.pi i.e.,
http://www.snopes.com/religion/pi.asp, or math.sin being "666".]

2. Use built-in functions/features as much as possible, as this are
the most tested. Don't roll your own -- you're not that good, instead
master the language. (How often do I invent a noun in English? Not
even "upcast"!) [Plus, guys with phds probably already did what you
need.] Use only very well known libraries -- numpy is okay (I hope!)
for example. An exception can be made while interfacing external
data, because others who create data may not have abided by rule #2.
In most cases (except gui programming, which again tackles the
external interfacing program) the more heavy-weight your API, the more
wrong you are.

3. In interpreted languages, avoid function calls, unless the
function does something significant. [e.g., Functional call overhead
tends to be worse that a dictionary lookup -- and yes I used timeit,
the overhead can be 100%.] Small functions and methods (and
callbacks) hamper good interpreted code. When writing functions, make
them operate on lists/dicts.

It is because of the above that I stopped writing object-oriented Perl.

So I want "big" functions that do a lot of work with few variable
names. Ideally, I'd create only variables that are relevant based on
the description of the algorithm. [Oh yeah, real programming is done
before the implementation in python or C++.]

My problems are compounded by the lack of indention-based scope, but I
see this as simply enforcing the full use of functional-programming
approaches.

</rant>
</ps>

On Sat, Jul 31, 2010 at 5:55 AM, Steven D'Aprano
<steve(a)remove-this-cybersource.com.au> wrote:
> On Sat, 31 Jul 2010 01:02:47 -0400, wheres pythonmonks wrote:
>
>
>>> Hint -- what does [].append(1) return?
>>>
>>>
>> Again, apologies from a Python beginner.  It sure seems like one has to
>> do gymnastics to get good behavior out of the core-python:
>>
>> Here's my proposed fix:
>>
>>  m['key'] = (lambda x: x.append(1) or x)(m.get('key',[]))
>>
>> Yuck!
>
> Yuk is right. What's wrong with the simple, straightforward solution?
>
> L = m.get('key', [])
> L.append(1)
> m['key'] = L
>
>
> Not everything needs to be a one-liner. But if you insist on making it a
> one-liner, that's what setdefault and defaultdict are for.
>
>
>
>> So I guess I'll use defaultdict with upcasts to dict as needed.
>
> You keep using that term "upcast". I have no idea what you think it
> means, so I have no idea whether or not Python does it. Perhaps you
> should explain what you think "upcasting" is.
>
>
>> On a side note:  does up-casting always work that way with shared
>> (common) data from derived to base?  (I mean if the data is part of
>> base's interface, will  b = base(child) yield a new base object that
>> shares data with the child?)
>
> Of course not. It depends on the implementation of the class.
>
>
> --
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list
>
From: Christian Heimes on
Am 30.07.2010 14:34, schrieb wheres pythonmonks:
> I was hoping not to do that -- e.g., actually reuse the same
> underlying data. Maybe dict(x), where x is a defaultdict is smart? I
> agree that a defaultdict is safe to pass to most routines, but I guess
> I could imagine that a try/except block is used in a bit of code where
> on the key exception (when the value is absent) populates the value
> with a random number. In that application, a defaultdict would have
> no random values.

defaultdict not only behaves like an ordinary dict except for missing
keys, it's also a subclass of Python's builtin dict type. You are able
to use a defaultdict just like a normal dict all over Python. You can
also provide your own custom implementation of a defaultdict that fits
your needs. All you have to do is subclass dict and implement a
__missing__ method. See
http://docs.python.org/library/stdtypes.html?highlight=__missing__#mapping-types-dict

Christian

From: John Posner on
On 7/31/2010 11:08 AM, Christian Heimes wrote:

> ... All you have to do is subclass dict and implement a
> __missing__ method. See
> http://docs.python.org/library/stdtypes.html?highlight=__missing__#mapping-types-dict
>

Caveat -- there's another description of defaultdict here:

http://docs.python.org/library/collections.html#collections.defaultdict

.... and it's bogus. This other description claims that __missing__ is a
method of defaultdict, not of dict.

This might cause considerable confusion, leading the reader to suspect
that __missing__ and default_factory fight it out for the right to
supply a default value. (__missing__ would win -- I tried it.)

The truth, as Christian says above and as Raymond Hettinger recently
pointed out [1], is that __missing__ is used to *define* defaultdict as
a subclass of dict -- it's not used *by* defaultdict.

-John

[1] http://mail.python.org/pipermail/python-list/2010-July/1248896.html
From: Christian Heimes on
> The truth, as Christian says above and as Raymond Hettinger recently
> pointed out [1], is that __missing__ is used to *define* defaultdict as
> a subclass of dict -- it's not used *by* defaultdict.

Your answer is confusing even me. ;)

Let me try an easier to understand explanation. defaultdict *implements*
__missing__() to provide the default dict behavior. You don't have to
subclass from defaultdict to get the __missing__() feature. It's part of
the dict interface since Python 2.5.

Christian

From: John Posner on
On 7/31/2010 2:00 PM, Christian Heimes wrote:
>
> Your answer is confusing even me. ;)

Yeah, I get that a lot. :-)


> Let me try an easier to understand explanation. defaultdict *implements*
> __missing__() to provide the default dict behavior.

In my experience, the word *implements* is commonly used in two ways,
nearly opposite to each other. Ex:

My company just implemented a version-control system.

Did your company (1) write the code for the version-control system, or
did it (2) put the system in use, by downloading an installer from the
Web and executing it?

-John