Question about None

Discussion in 'Python' started by Paul LaFollette, Jun 12, 2009.

  1. 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
    Paul LaFollette, Jun 12, 2009
    #1
    1. Advertising

  2. Paul LaFollette a écrit :
    > 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.


    This somehow goes against the whole philosophy of dynamic typing Python
    is based upon... But there are indeed cases where it makes sense and I
    assume you know what you're doing !-)

    > 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.


    Did you considered using properties (or custom descriptors) instead ?

    (snip - others already answered)
    Bruno Desthuilliers, Jun 12, 2009
    #2
    1. Advertising

  3. Paul LaFollette

    Jeff McNeil Guest

    On Jun 12, 10:05 am, Paul LaFollette <>
    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
    Jeff McNeil, Jun 12, 2009
    #3
  4. Hello,

    You're right, types.NoneType is not available in python 3.0, I wasn't
    aware of that change. Thanks for pointing it out.

    Best regards,
    Javier

    2009/6/12 Jeff McNeil <>:
    > On Jun 12, 10:05 am, Paul LaFollette <>
    > 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
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
    Javier Collado, Jun 12, 2009
    #4
  5. Paul LaFollette wrote:

    > 3) (this is purely philosophical but I am curious) Would it not be
    > more intuitive if
    > isinstance(None, <anything at all>) returned true?


    Good grief no!!!

    None is an object. It has a type, NoneType. It's *not* a string, or a float,
    or an int, or a list, so why would you want isinstance() to *lie* and say
    that it is?


    Python is good for testing these sorts of ideas:

    >>> _isinstance = isinstance
    >>> def isinstance(obj, type):

    .... if obj is None: return True
    .... return _isinstance(obj, type)
    ....
    >>> x = "parrot"
    >>> if isinstance(x, str):

    .... print x.upper()
    ....
    PARROT
    >>> x = None
    >>> if isinstance(x, str): print x.upper()

    ....
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute 'upper'




    --
    Steven
    Steven D'Aprano, Jun 13, 2009
    #5
  6. Paul LaFollette

    John Yeung Guest

    On Jun 13, 2:29 am, Steven D'Aprano
    <> wrote:
    > Paul LaFollette wrote:
    > > 3) (this is purely philosophical but I am curious)
    > > Would it not be more intuitive if
    > > isinstance(None, <anything at all>) returned true?

    >
    > Good grief no!!!
    >
    > None is an object. It has a type, NoneType. It's *not* a
    > string, or a float, or an int, or a list, so why would
    > you want isinstance() to *lie* and say that it is?


    Because you might want None to behave as though it were nothing at
    all.

    Paul LaFollette is probably thinking along the lines of formal logic
    or set theory. It's a little bit confused because programming isn't
    quite the same as math, and so it's a common question when designing
    and implementing programming languages how far to take certain
    abstractions. In some languages, nil, null, or none will try to
    behave as mathematically close to "nothing" (complete absence of
    anything) as possible, even though in reality they have to have some
    concrete implementation, such as perhaps being a singleton object.
    But mathematically speaking, it's intuitive that "nothing" would match
    any type.

    I find that it's somewhat like the confusion that often occurs
    regarding the all() function. Some people are surprised that all([])
    returns True, but it's the same logic behind the truth of the
    statement "every element of the empty set is an integer". It's also
    true that every element of the empty set is a float. Or an elephant.

    John
    John Yeung, Jun 13, 2009
    #6
  7. Paul LaFollette

    Paul Rubin Guest

    John Yeung <> writes:
    > Because you might want None to behave as though it were nothing at all.


    Sure, you might also want strings to behave as if they were ints, but
    wishing doesn't make it so.

    > But mathematically speaking, it's intuitive that "nothing" would match
    > any type.


    Completely wrong. The concept you're thinking of in denotational
    semantics is called "bottom", but bottom is not a value that functions
    can compute and return. It is really the absence of a value. We
    would say that a function semantically returns bottom, if calling does
    something like loop forever (never return), or it makes the program
    crash, or something like that. None is a value which in Haskell has a
    particular type. In some other languages, there are None-like values
    in more than one type, like in Haskell, for any type there is a
    Nothing for the Maybe of that type, but they all are of differing
    types, just like Python has an integer 0 and a floating point 0 that
    are of differing types.

    > I find that it's somewhat like the confusion that often occurs
    > regarding the all() function.


    It's the other way though, all([])=True makes sense,
    isinstance(None,int) does not.
    Paul Rubin, Jun 13, 2009
    #7
  8. Paul LaFollette

    Paul Rubin Guest

    Paul Rubin <http://> writes:
    > crash, or something like that. None is a value which in Haskell has a


    I got ahead of myself, of course I meant Python (the *next* sentence
    was going to mention Haskell). The corresponding concept in Haskell
    is called Nothing, which lives in a type functor called Maybe. I
    don't have time to go into it right now but there is a notion among
    language weenies these days that the presence of something like None
    (in Python) or Null (in Java, SQL, etc) is a wart in a language and
    that it's preferable to have something like Maybe.
    Paul Rubin, Jun 13, 2009
    #8
  9. >>>>> Paul Rubin <http://> (PR) wrote:

    >PR> Paul Rubin <http://> writes:
    >>> crash, or something like that. None is a value which in Haskell has a


    >PR> I got ahead of myself, of course I meant Python (the *next* sentence
    >PR> was going to mention Haskell). The corresponding concept in Haskell
    >PR> is called Nothing, which lives in a type functor called Maybe. I
    >PR> don't have time to go into it right now but there is a notion among
    >PR> language weenies these days that the presence of something like None
    >PR> (in Python) or Null (in Java, SQL, etc) is a wart in a language and
    >PR> that it's preferable to have something like Maybe.


    The reason is that in Haskell the type system doesn't have union types.
    Instead it has the disjoint sum, and Maybe is just one of them.
    Otherwise you could have used the union of Nothing and any other type.
    In Python there is no reason to use a disjoint sum as Python doesn't use
    static typing. You can use unions of types at your hearts desire. So I
    don't think there is not much difference between None and Nothing,
    except for the type system.

    Java, on the other hand does have static typing but does not have
    disjoint sums. So they have not much choice but to put null in every
    class-based type.
    --
    Piet van Oostrum <>
    URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
    Private email:
    Piet van Oostrum, Jun 13, 2009
    #9
  10. John Yeung wrote:

    > Paul LaFollette is probably thinking along the lines of formal logic
    > or set theory. It's a little bit confused because programming isn't
    > quite the same as math, and so it's a common question when designing
    > and implementing programming languages how far to take certain
    > abstractions. In some languages, nil, null, or none will try to
    > behave as mathematically close to "nothing" (complete absence of
    > anything) as possible, even though in reality they have to have some
    > concrete implementation, such as perhaps being a singleton object.
    > But mathematically speaking, it's intuitive that "nothing" would match
    > any type.


    I think you're wrong. Mathematically, you can't mix types like real numbers
    and sets: while 1+0 = 1, you can't expect to get a sensible result from
    1+{} or {1}∩0. (If that character between the set and zero ends up missing,
    it's meant to be INTERSECTION u'\u2229'.)

    Similarly, you can't add a scalar to a vector or matrix, even if one or the
    other is null.


    > I find that it's somewhat like the confusion that often occurs
    > regarding the all() function. Some people are surprised that all([])
    > returns True, but it's the same logic behind the truth of the
    > statement "every element of the empty set is an integer". It's also
    > true that every element of the empty set is a float. Or an elephant.


    So-called "vacuous truth". It's often useful to have all([]) return true,
    but it's not *always* useful -- there are reasonable cases where the
    opposite behaviour would be useful:

    if all(the evidence points to the Defendant's guilt) then:
    the Defendant is guilty
    execute(the Defendant)

    sadly means that if there is no evidence that a crime has been committed,
    the person accused of committing the imaginary crime will be executed.


    --
    Steven
    Steven D'Aprano, Jun 14, 2009
    #10
  11. Paul LaFollette

    Andre Engels Guest

    On Sat, Jun 13, 2009 at 7:23 PM, John Yeung<> wrote:

    > Paul LaFollette is probably thinking along the lines of formal logic
    > or set theory.  It's a little bit confused because programming isn't
    > quite the same as math, and so it's a common question when designing
    > and implementing programming languages how far to take certain
    > abstractions.  In some languages, nil, null, or none will try to
    > behave as mathematically close to "nothing" (complete absence of
    > anything) as possible, even though in reality they have to have some
    > concrete implementation, such as perhaps being a singleton object.
    > But mathematically speaking, it's intuitive that "nothing" would match
    > any type.


    I don't see why that would be the case. Something of the type "thingy"
    is ONE thingy. Nothing is ZERO thingies, so it is not something of the
    type "thingy". A car is a single car. Nothing is zero cars, which is
    not a car, just like two cars is not a car.


    --
    André Engels,
    Andre Engels, Jun 14, 2009
    #11
  12. Steven D'Aprano <> writes:
    > So-called "vacuous truth". It's often useful to have all([]) return true,
    > but it's not *always* useful -- there are reasonable cases where the
    > opposite behaviour would be useful:
    >
    > if all(the evidence points to the Defendant's guilt) then:
    > the Defendant is guilty
    > execute(the Defendant)
    >
    > sadly means that if there is no evidence that a crime has been committed,
    > the person accused of committing the imaginary crime will be executed.


    This is a bad example. Someone is not convicted of a crime just because
    all the available evidence points towards their guilt. There may be
    very little evidence altogether, or it might just be circumstancial, or
    unconvincing. Even though it may all point towards the defendent's
    guilt, it doesn't mean they will be convicted. There needs to be enough
    evidence to convince the jury. So it would be something like:

    if sum(guilt_weight(e) for e in evidence) > GUILT_THRESHOLD:
    the defendant is guilty
    ...

    --
    Arnaud
    Arnaud Delobelle, Jun 14, 2009
    #12
  13. Paul LaFollette

    Aaron Brady Guest

    On Jun 14, 10:02 am, Arnaud Delobelle <> wrote:
    snip
    > guilt, it doesn't mean they will be convicted.  There needs to be enough
    > evidence to convince the jury.  So it would be something like:
    >
    > if sum(guilt_weight(e) for e in evidence) > GUILT_THRESHOLD:
    >    the defendant is guilty
    >    ...
    >
    > --
    > Arnaud


    You all are only two months late.

    http://groups.google.com/group/comp.lang.python/msg/7b63d0d11246ecad

    Can't argue with results.
    Aaron Brady, Jun 14, 2009
    #13
  14. Paul LaFollette

    Paul Rubin Guest

    Andre Engels <> writes:
    > I don't see why that would be the case. Something of the type "thingy"
    > is ONE thingy. Nothing is ZERO thingies, so it is not something of the
    > type "thingy". A car is a single car. Nothing is zero cars, which is
    > not a car, just like two cars is not a car.


    That seems to confuse values with collections of them. A car is not
    the same as a one-element list of cars. Nothing is not the same as a
    zero-element list of cars.
    Paul Rubin, Jun 14, 2009
    #14
  15. Paul LaFollette

    Andre Engels Guest

    On Sun, Jun 14, 2009 at 9:37 PM, Paul Rubin<http://> wrote:
    > Andre Engels <> writes:
    >> I don't see why that would be the case. Something of the type "thingy"
    >> is ONE thingy. Nothing is ZERO thingies, so it is not something of the
    >> type "thingy". A car is a single car. Nothing is zero cars, which is
    >> not a car, just like two cars is not a car.

    >
    > That seems to confuse values with collections of them.  A car is not
    > the same as a one-element list of cars.  Nothing is not the same as a
    > zero-element list of cars.


    So you are of the opinion that "nothing" _is_ a car?



    --
    André Engels,
    Andre Engels, Jun 14, 2009
    #15
  16. Paul LaFollette

    Paul Rubin Guest

    Andre Engels <> writes:
    > > That seems to confuse values with collections of them.  A car is not
    > > the same as a one-element list of cars.  Nothing is not the same as a
    > > zero-element list of cars.

    >
    > So you are of the opinion that "nothing" _is_ a car?


    Eh? No of course not. a != b and b != c does not mean a==c.
    I don't understand what you're getting at.
    Paul Rubin, Jun 14, 2009
    #16
  17. Paul LaFollette

    Andre Engels Guest

    On Sun, Jun 14, 2009 at 10:21 PM, Paul
    Rubin<http://> wrote:
    > Andre Engels <> writes:
    >> > That seems to confuse values with collections of them.  A car is not
    >> > the same as a one-element list of cars.  Nothing is not the same as a
    >> > zero-element list of cars.

    >>
    >> So you are of the opinion that "nothing" _is_ a car?

    >
    > Eh?  No of course not.  a != b and b != c does not mean a==c.
    > I don't understand what you're getting at.


    I was making a point that I don't agree that "nothing" would match any
    type. The reason was that anything of the type car is one car, not two
    cars or zero cars, but "nothing" is zero cars. You don't agree with
    me, so apparently you are of the opinion that "nothing" would be a
    car.

    --
    André Engels,
    Andre Engels, Jun 14, 2009
    #17
  18. Paul LaFollette

    Paul Rubin Guest

    Andre Engels <> writes:
    > I was making a point that I don't agree that "nothing" would match any
    > type. The reason was that anything of the type car is one car, not two
    > cars or zero cars, but "nothing" is zero cars. You don't agree with
    > me, so apparently you are of the opinion that "nothing" would be a car.


    I don't agree that "nothing" is "zero cars". Just like I don't agree
    that the empty set, the empty list, and the empty string are the same
    thing.
    Paul Rubin, Jun 14, 2009
    #18
  19. Paul LaFollette

    Terry Reedy Guest

    Steven D'Aprano wrote:
    >
    > So-called "vacuous truth". It's often useful to have all([]) return
    > true, but it's not *always* useful -- there are reasonable cases
    > where the opposite behaviour would be useful:
    >
    > if all(the evidence points to the Defendant's guilt) then: the
    > Defendant is guilty execute(the Defendant)
    >
    > sadly means that if there is no evidence that a crime has been
    > committed, the person accused of committing the imaginary crime will
    > be executed.


    It seems to me that the absurd conclusion implied by the theorem
    invalidates the theorem rather than supporting your point. No evidence
    is only the endpoint of a continuum. Suppose that 'all' is one teensy
    weensy bit of evidence. A drunked bystander gives a vague description
    that fits. Or twenty years before, the defendent argued with the
    deceased and said 'I wish you were dead'. Should the person be executed?
    I say not. You?

    Of course, a person would only be a defendant in the absence of evidence
    under a depraved regime that would not much care if there were.

    Try finding another 'reasonable case'.

    Terry Jan Reedy
    Terry Reedy, Jun 15, 2009
    #19
  20. Paul LaFollette

    Aaron Brady Guest

    On Jun 14, 12:37 pm, Paul Rubin <http://> wrote:
    > Andre Engels <> writes:

    snip
    > > type "thingy". A car is a single car. Nothing is zero cars, which is
    > > not a car, just like two cars is not a car.

    >
    > That seems to confuse values with collections of them.  A car is not
    > the same as a one-element list of cars.  Nothing is not the same as a
    > zero-element list of cars.


    Collections are a mathematical (ideal, cognitive) construct.
    Aaron Brady, Jun 15, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Freeman
    Replies:
    8
    Views:
    7,619
    tcena9
    Feb 16, 2011
  2. length power
    Replies:
    2
    Views:
    68
    Rustom Mody
    Apr 10, 2014
  3. Skip Montanaro
    Replies:
    0
    Views:
    50
    Skip Montanaro
    Apr 10, 2014
  4. Johannes Schneider

    Re: why i have the output of [None, None, None]

    Johannes Schneider, Apr 10, 2014, in forum: Python
    Replies:
    0
    Views:
    44
    Johannes Schneider
    Apr 10, 2014
  5. Terry Reedy
    Replies:
    0
    Views:
    54
    Terry Reedy
    Apr 10, 2014
Loading...

Share This Page