c[:]()

Steve Holden steve at holdenweb.com
Thu May 31 16:37:43 EDT 2007


Warren Stringer wrote:
>>>> c[:] holds many behaviors that change dynamically.
>>> I've absolutely no clue what that sentence means.  If c[:] does
>>> behave differently than c, then somebody's done something
>>> seriously weird and probably needs to be slapped around for
>>> felonious overriding.
> 
> I'm still a bit new at this, was wondering why c[:]() doesn't work, and
> implicitly wondering why it *shouldn't* work. 
> 
>>>> So c[:]() -- or the more recent go(c)() -- executes all those
>>>> behaviors.

No it doesn't. See below.

> 
> Oops meant to say do(c)(), not "go", which matches a prior post. 
> 
>>> Still no clue.
>>>
>>>> This is very useful for many performers.
>>> What are "performers"?
> 
> Real people, like musicians, and their proxies in code that passes around
> real-time events that may be rendered, recorded, and played back.
> 
>>>> The real world example that I'm working one is a collaborative
>>>> visual music performance. So c can contain wrapped MIDI events
>>>> or sequencer behaviors. c may get passed to a scheduler to
>>>> execute those events, or c may get passed to a pickler to
>>>> persist the performance.
>>> I still don't see how c[:] is any different from c.
>>>
>> It isn't. The OP is projecting a wish for a function call on a list to
>> be interpreted as a call on each member of the list with the same
>> arguments. The all-members slice notation is a complete red herring.
> 
> Just looked up "red herring wiki" hope I wasn't being misleading -- at least
> not intentionally. c[:] is the simplest case for a broad range of behaviors.
> Perhaps, I should have said c[selector()]() ???  but, no, that makes the
> question more complex ... still 
> 
>> It would require a pretty fundamental re-think to give such a construct
>> sensible and consistent semantics, I think.
> 
> What do you mean?
> 
> If c[:]() works, the so does this, using real world names
>  
> 	orchestra[:].pickle()
> 	orchestra[conductor()].sequence() 
> 
> Though, I'm already starting to prefer:
> 
> 	do(orchestra).pickle() 
> 	do(orchestra(conductor)).sequence()  
> 
Yes, dammit, but c[:]() *DOESN'T WORK* unless you have made some pretty 
crufty changes to the underlying object.

> Perhaps, this is what you mean by "sensible and consistent semantics"
> 
> I just read Alex Martelli's post in the "rats! Varargs" thread about how
> list and tupples are implemented. I want to understand implementation before
> suggesting changes. Maybe c[:]() isn't so simple to fix, after all?
> 
> 
This is what I'm having difficulty understanding. You said, in your 
original post (which, by the way, hijacked another thread about 
something completely different):

> I want to call every object in a tupple, like so:
> 
[By the way, that's "tuple", not "tupple"]
> #------------------------------------------
> def a: print 'a'
> def b: print 'b'
> c = (a,b) 
> 
>>>> >>>c[:]()  # i wanna
>  TypeError: 'tupple' object is not callable
> 
>>>> >>>c[0]()  # expected
> a
>>>> >>>c[:][0] # huh?
> a

This is what I just don't believe. And, of course, the use of "tupple" 
above tells us that this *wasn't" just copied and pasted from an 
interactive session.

>>>> >>> [i() for i in c] # too long and ...huh?
> a
> b
> [None,None]
> #------------------------------------------
This is also clearly made up.

In a later email you say:

> why does c[:][0]() work but c[:]() does not? 

The reason for this is that c[:][0] is a function, a single item from a 
tuple of functions. c[:], however, is a tuple of functions, and cannot 
be called as a function itself. No matter how much you would like it to 
be. Python's chief virtue is obviousness, and this behavior would be 
very non-obvious. You also don't explain when Python should do if you 
happen to have something other than a function (say a string or a 
floating-point number) in the tuple.

You also said:

> Why does c[0]() has exactly the same results as c[:][0]() ? 

The reason for this is that c is exactly the same as c[:]. The slicing 
notation "[:]" tells the interpreter to use a tuple consisting of 
everything in the tuple to which it's applied. Since the interpreter 
knows that tuples are immutable (can't be changed), it just uses the 
same tuple -- since the immutability there's no way that a difference 
could arise between the tuple and a copy of the tuple, Python doesn't 
bother to make a copy.

This behavior is *not* observed with lists, because lists are mutable.

I realise you are trying to find ways to make Python more productive for 
you, and there's nothing wrong with that. But consider the following, 
which IS copied and pasted:

 >>> def a():
...   print "A"
...
 >>> def b():
...   print "B"
...
 >>> c = (a, b)
 >>> c
(<function a at 0x7ff4f764>, <function b at 0x7ff4f64c>)
 >>> c[:]
(<function a at 0x7ff4f764>, <function b at 0x7ff4f64c>)
 >>> c[0]()
A
 >>> c[1]()
B
 >>> c()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
 >>> c[:]()
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
 >>>

I think the fundamental mistake you have made is to convince yourself that

     c[:]()

is legal Python. It isn't, it never has been.

regards
  Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC/Ltd           http://www.holdenweb.com
Skype: holdenweb      http://del.icio.us/steve.holden
------------------ Asciimercial ---------------------
Get on the web: Blog, lens and tag your way to fame!!
holdenweb.blogspot.com        squidoo.com/pythonology
tagged items:         del.icio.us/steve.holden/python
All these services currently offer free registration!
-------------- Thank You for Reading ----------------




More information about the Python-list mailing list