<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: The Magic Sentinel</title>
	<atom:link href="http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/</link>
	<description></description>
	<lastBuildDate>Wed, 08 Sep 2010 10:58:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Ben Finney</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62875</link>
		<dc:creator>Ben Finney</dc:creator>
		<pubDate>Mon, 08 Dec 2008 00:29:02 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62875</guid>
		<description>As pointed out, the trouble with Ian&#039;s example is that different zero-item tuples are *not* guaranteed to be unique:

    Python 2.5.2 (r252:60911, Sep 29 2008, 22:32:35) 
    [GCC 4.3.2] on linux2
    Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
    \&gt;&gt;&gt; foo = ()
    \&gt;&gt;&gt; bar = ()
    \&gt;&gt;&gt; foo == bar
    True
    \&gt;&gt;&gt; foo is bar
    True

I dislike it for that reason, but also because it&#039;s not clear that the zero-item tuple might not *mean* something else. This also rules out, for me, other objects that seem to have a potential meaning in themselves.

So my preference is for a bald instance of the ‘object’ type:

    \&gt;&gt;&gt; foo = object()
    \&gt;&gt;&gt; bar = object()
    \&gt;&gt;&gt; foo == bar
    False
    \&gt;&gt;&gt; foo is bar
    False

The statement creating the object is pretty clearly not creating an object that is useful for *anything* other than being unique. This makes it distinct in a way that a tuple, of whatever length, is not; and so that makes it uniquely suitable for defining a sentinel value.</description>
		<content:encoded><![CDATA[<p>As pointed out, the trouble with Ian&#8217;s example is that different zero-item tuples are <em>not</em> guaranteed to be unique:</p>

<pre><code>Python 2.5.2 (r252:60911, Sep 29 2008, 22:32:35) 
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
\&gt;&gt;&gt; foo = ()
\&gt;&gt;&gt; bar = ()
\&gt;&gt;&gt; foo == bar
True
\&gt;&gt;&gt; foo is bar
True
</code></pre>

<p>I dislike it for that reason, but also because it&#8217;s not clear that the zero-item tuple might not <em>mean</em> something else. This also rules out, for me, other objects that seem to have a potential meaning in themselves.</p>

<p>So my preference is for a bald instance of the ‘object’ type:</p>

<pre><code>\&gt;&gt;&gt; foo = object()
\&gt;&gt;&gt; bar = object()
\&gt;&gt;&gt; foo == bar
False
\&gt;&gt;&gt; foo is bar
False
</code></pre>

<p>The statement creating the object is pretty clearly not creating an object that is useful for <em>anything</em> other than being unique. This makes it distinct in a way that a tuple, of whatever length, is not; and so that makes it uniquely suitable for defining a sentinel value.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Cory</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62672</link>
		<dc:creator>Cory</dc:creator>
		<pubDate>Sun, 07 Dec 2008 06:08:45 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62672</guid>
		<description>Alec and Ian:

I tend to use (1,) as my sentinel.

&gt;&gt;&gt; MARKER1 = (1,)

&gt;&gt;&gt; MARKER2 = (1,)

&gt;&gt;&gt; MARKER1 is MARKER2

False

Thus you can use it to give different sentinels distinct instances.  I feel Ian&#039;s solution is a bit .. much .. for such a simple thing.</description>
		<content:encoded><![CDATA[<p>Alec and Ian:</p>

<p>I tend to use (1,) as my sentinel.</p>

<p>&gt;&gt;&gt; MARKER1 = (1,)</p>

<p>&gt;&gt;&gt; MARKER2 = (1,)</p>

<p>&gt;&gt;&gt; MARKER1 is MARKER2</p>

<p>False</p>

<p>Thus you can use it to give different sentinels distinct instances.  I feel Ian&#8217;s solution is a bit .. much .. for such a simple thing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62379</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Fri, 05 Dec 2008 21:12:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62379</guid>
		<description>Mostly I don&#039;t use a class when I want to define `__repr__`.  I used to just use a NoDefault class, but in generated documentation it looks bad.  I don&#039;t pickle things very often so that aspect hasn&#039;t come up.  Also these objects should really only be used locally in a module, they aren&#039;t something you should hold onto... but of course if you did for some reason, you&#039;d end up with a very hard to debug problem.  I suspect by doing `del NoDefault` that you&#039;d at least stop pickle from unpickling the object.</description>
		<content:encoded><![CDATA[<p>Mostly I don&#8217;t use a class when I want to define <code>__repr__</code>.  I used to just use a NoDefault class, but in generated documentation it looks bad.  I don&#8217;t pickle things very often so that aspect hasn&#8217;t come up.  Also these objects should really only be used locally in a module, they aren&#8217;t something you should hold onto&#8230; but of course if you did for some reason, you&#8217;d end up with a very hard to debug problem.  I suspect by doing <code>del NoDefault</code> that you&#8217;d at least stop pickle from unpickling the object.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ken Kinder</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62378</link>
		<dc:creator>Ken Kinder</dc:creator>
		<pubDate>Fri, 05 Dec 2008 21:08:46 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62378</guid>
		<description>On a totally off-topic note, if I don&#039;t fill in my email and I hit &quot;post&quot;, I&#039;m asked for the &quot;admin&quot; login via http authentication.</description>
		<content:encoded><![CDATA[<p>On a totally off-topic note, if I don&#8217;t fill in my email and I hit &#8220;post&#8221;, I&#8217;m asked for the &#8220;admin&#8221; login via http authentication.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ken Kinder</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62377</link>
		<dc:creator>Ken Kinder</dc:creator>
		<pubDate>Fri, 05 Dec 2008 21:08:00 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62377</guid>
		<description>There have been a handful of times I&#039;ve come across similar patterns, but I&#039;ve skipped your step of making NoDefault an object. This works just as well:

    class NoDefault(object):
        pass

    def getuser(username, default=NoDefault):
        ...
        if default is NoDefault:
            ...</description>
		<content:encoded><![CDATA[<p>There have been a handful of times I&#8217;ve come across similar patterns, but I&#8217;ve skipped your step of making NoDefault an object. This works just as well:</p>

<pre><code>class NoDefault(object):
    pass

def getuser(username, default=NoDefault):
    ...
    if default is NoDefault:
        ...
</code></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: rgz</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62360</link>
		<dc:creator>rgz</dc:creator>
		<pubDate>Fri, 05 Dec 2008 07:19:29 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62360</guid>
		<description>What Matthew said, but simpler, just create the sentinel class and use that, use a naming convention like &#039;NoDefaultSentinel&#039; and that&#039;s it, but I find it difficult to find a sane use case for that, if you have control over the call why don&#039;t you use the signature def(user, defualt=None,nodefault=False): ...?</description>
		<content:encoded><![CDATA[<p>What Matthew said, but simpler, just create the sentinel class and use that, use a naming convention like &#8216;NoDefaultSentinel&#8217; and that&#8217;s it, but I find it difficult to find a sane use case for that, if you have control over the call why don&#8217;t you use the signature def(user, defualt=None,nodefault=False): &#8230;?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Calvin Spealman</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62352</link>
		<dc:creator>Calvin Spealman</dc:creator>
		<pubDate>Fri, 05 Dec 2008 00:10:18 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62352</guid>
		<description>Just create an instance of object for your sentinel</description>
		<content:encoded><![CDATA[<p>Just create an instance of object for your sentinel</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Matthew Scott</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62350</link>
		<dc:creator>Matthew Scott</dc:creator>
		<pubDate>Thu, 04 Dec 2008 23:23:18 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62350</guid>
		<description>Something to keep in mind with regards to sentinel values is whether or not you want to be able to pickle them.

Schevo uses a metaclass to provide __repr__ and __str__ for the class itself, as well as some metaclass subclasses that also provide __nonzero__, __cmp__, __len__ for Schevo&#039;s special UNASSIGNED constant.

See http://github.com/gldnspud/schevo/tree/master/schevo/constant.py

When pickling an instance of a sentinel class, you have a situation where the in-memory singleton instance of a sentinel class is not the same object as an unpickled instance of the same class, therefore &quot;is&quot; comparisons won&#039;t work.

By pickling the class itself, when the sentinel is unpickled it becomes a reference to the class itself, so &quot;is&quot; comparisons work as intended.</description>
		<content:encoded><![CDATA[<p>Something to keep in mind with regards to sentinel values is whether or not you want to be able to pickle them.</p>

<p>Schevo uses a metaclass to provide <strong>repr</strong> and <strong>str</strong> for the class itself, as well as some metaclass subclasses that also provide <strong>nonzero</strong>, <strong>cmp</strong>, <strong>len</strong> for Schevo&#8217;s special UNASSIGNED constant.</p>

<p>See <a href="http://github.com/gldnspud/schevo/tree/master/schevo/constant.py" rel="nofollow">http://github.com/gldnspud/schevo/tree/master/schevo/constant.py</a></p>

<p>When pickling an instance of a sentinel class, you have a situation where the in-memory singleton instance of a sentinel class is not the same object as an unpickled instance of the same class, therefore &#8220;is&#8221; comparisons won&#8217;t work.</p>

<p>By pickling the class itself, when the sentinel is unpickled it becomes a reference to the class itself, so &#8220;is&#8221; comparisons work as intended.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: DZ</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62224</link>
		<dc:creator>DZ</dc:creator>
		<pubDate>Thu, 04 Dec 2008 08:13:11 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62224</guid>
		<description>What is &quot;del _NoDefault&quot; for?</description>
		<content:encoded><![CDATA[<p>What is &#8220;del _NoDefault&#8221; for?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alec</title>
		<link>http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/comment-page-1/#comment-62196</link>
		<dc:creator>Alec</dc:creator>
		<pubDate>Thu, 04 Dec 2008 05:52:57 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/12/03/the-magic-sentinel/#comment-62196</guid>
		<description>Using an empty tuple as a sentinel seems like a bad idea for similar reasons as using None.  It&#039;s a valid value and it&#039;s not necessarily unique:

&gt;&gt;&gt; a = ()

&gt;&gt;&gt; b = ()

&gt;&gt;&gt; a is b

True

Though it&#039;s not a singleton like None, its immutability means that any variable set to the same value may point to the same object in memory.  All the more reason to use your custom sentinel, or at least [] or object().</description>
		<content:encoded><![CDATA[<p>Using an empty tuple as a sentinel seems like a bad idea for similar reasons as using None.  It&#8217;s a valid value and it&#8217;s not necessarily unique:</p>

<p>&gt;&gt;&gt; a = ()</p>

<p>&gt;&gt;&gt; b = ()</p>

<p>&gt;&gt;&gt; a is b</p>

<p>True</p>

<p>Though it&#8217;s not a singleton like None, its immutability means that any variable set to the same value may point to the same object in memory.  All the more reason to use your custom sentinel, or at least [] or object().</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.698 seconds -->
