[Tutor] s.insert(i, x) explanation in docs for Python 3.4 confusing to me

Cameron Simpson cs at zip.com.au
Sun Jan 17 16:48:59 EST 2016


On 17Jan2016 10:49, Alex Kleider <akleider at sonic.net> wrote:
>>>Can you please clarify the last bit:
>>>"specially recognised as nor in the normal domain for that value."
>>
>>s/nor/not/
>
>May I trouble you further by specifically asking about 's/nor/not/'- I don't 
>get what that's about.

Ah. Ed, sed, vi, vim speak. Substitute: replace "nor" with "not". The "nor" is 
a typo. I meant "not in the normal domain".

>Has it to do with this 'nor': http://www.merriam-webster.com/dictionary/nor?

"Nor" is indeed a useful word, but it wasn't the word I intended.

[...]
>>It isn't always None. [...]
>>you might need to make a unique sentinel value entirely for your
>>object. The normal way to do this is simply to make a new object:
>>
>> sentinel = object()
>>
>>This is a minimal Python object which nobody else is using. Its value
>>is nothing special (or even meaningful), so you merely want to check
>>whether what you've got is that particular object, using "is".
>>Untested example sketch:
>>
>> class SomethingLikeAQueue:
>>
>>   def __init__(self,......):
>>     self.things = []
>>     # private value to use as a sentinel, unique per instance
>>     self._sentinel = object()
>>     ... whatever else ...
>>
>>   def put(self, value):
>>     # public method to put a new value
>>     if value is self._sentinel:
>>       raise ValueError("you may not put the sentinel value")
>>     self._put(value)
>>
>>   def _put(self, value):
>>     # private method accepting any value including the sentinel
>>     # we will use receipt of the sentinel to process the things and
>>stop      # further acceptance of more things
>>     if value is self._sentinel:
>>       things = self.things
>>       self.things = None  # will make the .append blow up
>>       ... process things here maybe ...
>>     else:
>>       things.append(value)     #### ??? self.things.append(value)
>>
>>   def close(self):
>>     # send the sentinel to indicate no more things
>>     self._put(self._sentinel)
[...]
>ps Am I correct that towards the end of your code it should have been
>    self.things.append(value)

Yes. I probably let myself be lazy because of the earlier "things = 
self.things" in the "true" branch of the "if", where I did it to keep the 
former value of "things" for processing before scrubbing self.things. Of 
course, that way lies buggy code.

I do occasionally pull various object attributes into local variables for 
performance and readability; when I do that it really should be right at the 
top of the function just after any parameter processing, thus:

  class Foo:
    def method(self, foo, bar):
      things = self.things
      for item in foo:
        things.append(item) # or whatever

There are usually two reasons I would do that ("things = self.things" at the 
top): (a) for readability if I'm going to be saying "things" a lot - 
"self.things" may be cumbersome/wordy, making the code very verbose or (b) for 
performance.

To the latter: saying "self.things" requires Python to look up the things 
attribute in "self" every time you use it; if you put it into a local variable 
then Python has direct access to it from the function scope - in CPython his is 
very efficient, and likely so in other Python implementations.

Don't forget that because both "self.things" and "things" refer to the same 
list object (in the example earlier) there's no need to have any final 
"self.things = things" because both are acting on the same list.

Cheers,
Cameron Simpson <cs at zip.com.au>


More information about the Tutor mailing list