Again, a personal thank you.
More often than not, when answering one thing, you teach me about
other things.  The 'thing' thing is only the latest.  Of course
I knew that using a name bound to a collection would effect the
contents of the collection but it would never have occurred to me
to use it to advantage as you describe.
Another "Ah, Ha!" experience.
Alex

On 2016-01-17 13:48, Cameron Simpson wrote:
On 17Jan2016 10:49, Alex Kleider <aklei...@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 <c...@zip.com.au>
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to