LangWart: Method congestion from mutate multiplicty

88888 Dihedral dihedral88888 at googlemail.com
Sun Feb 10 09:33:59 EST 2013


Steven D'Aprano於 2013年2月9日星期六UTC+8上午11時36分52秒寫道:
> Rick Johnson wrote:
> 
> 
> 
> > The solution is simple. Do not offer the "copy-mutate" methods and force
> 
> > all mutation to happen in-place:
> 
> > 
> 
> > py> l = [1,2,3]
> 
> > py> l.reverse
> 
> > py> l
> 
> > [3,2,1]
> 
> > 
> 
> > If the user wants a "mutated copy" he should explicitly create a new
> 
> > object and then apply the correct mutator method:
> 
> > 
> 
> > py> a1 = [1,2,3]
> 
> > py> a2 = list(a1).reverse()
> 
> 
> 
> 
> 
> Oh wow, Rick has re-discovered programming in Python during the mid to late
> 
> 1990s!
> 
> 
> 
> I was there, and I remember what it was like. For about a month, you try
> 
> hard to follow Rick's prescription. Then you realise that with a small
> 
> helper function, you can halve the amount of code it takes to do a common
> 
> operation:
> 
> 
> 
> def reversed(sequence):
> 
>     seq = list(sequence)
> 
>     seq.reverse()
> 
>     return seq
> 
> 
> 
> 
> 
> Soon you've copied this reversed() function into all your projects. And of
> 
> course, they start to diverge... in project A, you only care about lists.
> 
> In project B, you realise that you also need to support tuples and strings:
> 
> 
> 
> 
> 
> def reversed(sequence):
> 
>     seq = sequence[:]
> 
>     try:
> 
>         seq.reverse()
> 
>     except AttributeError:
> 
>         seq = seq[::-1]
> 
>     return seq
> 
> 
Will a temprary new list be formed here?
If it is not necessary, I'll prefer a reverse 
generator for all lists to save the heap space
and the GC burden.


> 
> which in project C you realise can be shortened:
> 
> 
> 
> def reversed(sequence):
> 
>     return sequence[::-1]
> 
> 
> 
> 
> 
> until you get to project D when you realise that you also want this to work
> 
> on dicts:
> 
> 
> 
> def reversed(sequence):
> 
>     everything = list(sequence)
> 
>     return everything[::-1]
> 
> 
> 
> 
> 
> and then in project E you wonder why reversed(string) returns a list:
> 
> 
> 
> def reversed(sequence):
> 
>     everything = list(sequence)[::-1]
> 
>     if isinstance(sequence, tuple):
> 
>         return tuple(everything)
> 
>     elif isinstance(sequence, str):
> 
>         return ''.join(everything)
> 
>     return everything
> 
> 
> 
> 
> 
> and then finally you learn about iterators and generators and become more
> 
> comfortable with a flow-based programming paradigm and generators:
> 
> 
> 
> def reversed(sequence):
> 
>     for item in list(sequence)[::-1]:
> 
>         yield item
> 
> 
> 
> at which point you realise that, hell, this is so useful that pretty much
> 
> everyone has implemented it a dozen times or more in their own projects,
> 
> and you start to agitate for it to be added to the builtins so that there
> 
> is *one* implementation, done *right*, that everyone can use.
> 
> 
> 
> And then you get told that Guido's time machine has struck again, because
> 
> Python has already had this since Python 2.4.
> 
> 
> 
> 
> 
> 
> 
> -- 
> 
> Steven




More information about the Python-list mailing list