Question about None

Jeff McNeil jeff at jmcneil.net
Fri Jun 12 10:55:41 EDT 2009


On Jun 12, 10:05 am, Paul LaFollette <paul.lafolle... at gmail.com>
wrote:
> Kind people,
>
> Using Python 3.0 on a Gatesware machine (XP).
> I am building a class in which I want to constrain the types that can
> be stored in various instance variables.  For instance, I want to be
> certain that self.loc contains an int.  This is straightforward (as
> long as I maintain the discipline of changing loc through a method
> rather than just twiddling it directly.
>
>   def setLoc(lo):
>     assert isinstance(lo, int), "loc must be an int"
>     self.loc = lo
>
> does the trick nicely.
>
> However, I also want to constrain self.next to be either an instance
> of class Node, or None.  I would think that the following should work
> but it doesn't.
>
>   def setNext(nxt):
>     assert isinstance(nxt, (Node, NoneType)), "next must be a Node"
>     self.next = nxt
>
> since type(Node) responds with <class, 'NoneType'> but the assertion
> above gives "name 'NoneType' is not defined" suggesting that NoneType
> is some sort of quasi-class.
>
>   def setNext(nxt):
>     assert nxt==None or isinstance(nxt, Node), "next must be a Node"
>     self.next = nxt
>
> works ok, but it's uglier than it ought to be.
>
> So, I have three questions.
>
> 1) Why doesn't isinstance(nxt, (Node, NoneType)) work?
> 2) is their a less ugly alternative that what I am using?
> 3) (this is purely philosophical but I am curious)  Would it not be
> more intuitive if
> isinstance(None, <anything at all>) returned true?
>
> Thank you for your kind attention.
> Paul

1. The problem is described clearly by that Exception. The 'NoneType'
name isn't bound to any objects at that current scope.  I know that
with 2.6, you can import 'types.NoneType' but I don't believe the 3.0
types module includes NoneType.  Someone else will have to clarify
that as I don't have 3.0 installed.

2. A less ugly alternative? You could use the accepted method of
testing against None:

if var is None:
    do_stuff()

The use of the 'is' operator checks whether objects are exactly the
same (id(var) == id(None)) as opposed to 'isinstance' or '==.'

You might also try defining descriptors in order to make your type
checks slightly more transparent. That might be confusing to other
users of your class, though. Not many people expect a TypeError from
an attribute assignment.

3. None is an instance of NoneType. Why should isinstance return True
when it's tested against other types?

HTH,

Jeff
mcjeff.blogspot.com



More information about the Python-list mailing list