None Python error/bug? - python

In Python you have the None singleton, which acts pretty oddly in certain circumstances:
>>> a = None
>>> type(a)
<type 'NoneType'>
>>> isinstance(a,None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types
So first off, <type 'NoneType'> displays that None is not a type, but that NoneType is. Yet when you run isinstance(a,NoneType), it responds with an error: NameError: name 'NoneType' is not defined
Now, given this, if you have a function with an input default set to None, and need to check, you would do the following:
if variable is None:
#do something
else:
#do something
what is the reason that I cannot do the following instead:
if isinstance(variable,None): #or NoneType
#do something
else:
#do something
I am just looking for a detailed explanation so I can better understand this
Edit: good application
Lets say I wanted to use isinstance so that I can do something if variable is a variety of types, including None:
if isinstance(variable,(None,str,float)):
#do something

You can try:
>>> variable = None
>>> isinstance(variable,type(None))
True
>>> variable = True
>>> isinstance(variable,type(None))
False
isinstance takes 2 arguments isinstance(object, classinfo) Here, by passing None you are setting classinfo to None, hence the error. You need pass in the type.

None is not a type, it is the singleton instance itself - and the second argument of isinstance must be a type, class or tuple of them. Hence, you need to use NoneType from types.
from types import NoneType
print isinstance(None, NoneType)
print isinstance(None, (NoneType, str, float))
True
True
Although, I would often be inclined to replace isinstance(x, (NoneType, str, float)) with x is None or isinstance(x, (str, float)).

None is the just a value of types.NoneType, it's not a type.
And the error is clear enough:
TypeError: isinstance() arg 2 must be a class, type, or tuple of
classes and types
From the docs:
None is the sole value of types.NoneType. None is frequently used to represent
the absence of a value, as when default arguments are not passed to a
function.
You can use types.NoneType
>>> from types import NoneType
>>> isinstance(None, NoneType)
True
is operator also works fine:
>>> a = None
>>> a is None
True

None is a value(instance) and not a type. As the error message shows, isinstance expects the second argument to be a type.
The type of None is type(None), or Nonetype if you import it (from types import NoneType)
Note: the idiomatic way to do the test is variable is None. Short and descriptive.

Related

Is there a way to create SimpleNamespace with boolean value false?

I am trying to create a SimpleNamespace with false value, but it is not working for me.
EMPTY = types.SimpleNamespace(__bool__=lambda self: False)
assert bool(EMPTY) == False # raises error!!
Is there a way to create SimpleNamespace with boolean value false?
It is not possible to give custom, "real" methods to individual instances of a class. In the original code, EMPTY.__bool__ is not a method, but an ordinary function. You can see this by trying to invoke it explicitly:
>>> EMPTY = types.SimpleNamespace(__bool__=lambda self: False)
>>> EMPTY.__bool__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'self'
See also Adding a Method to an Existing Object Instance. While it's possible - following the advice there - to make EMPTY.__bool__ behave like a method:
>>> EMPTY = types.SimpleNamespace()
>>> EMPTY.__bool__ = types.MethodType(lambda self: False, EMPTY)
>>> EMPTY.__bool__()
False
that will still be ignored by bool:
>>> bool(EMPTY)
True
The implementation of bool looks up __bool__ directly on the class, because it has no reason to expect an instance to have such an attribute.
Instead, we need to have our own class, with an actual method named __bool__ that does the right thing. Thus:
class PossiblyEmptyNamespace(types.SimpleNamespace):
"""A namespace that is falsey when it doesn't contain anything."""
def __bool__(self):
return bool(vars(self))
Now we can test that:
>>> EMPTY = PossiblyEmptyNamespace()
>>> bool(EMPTY)
False
>>> EMPTY.foo = 'bar'
>>> bool(EMPTY) # oops, not actually empty any more.
True
As mentioned in the comments, you'll need to make a subclass. Dunder methods like __bool__ are generally looked up on the class, not the specific instance, so setting a field on an instance will do you no good in this case.
from types import SimpleNamespace
class FalsyNamespace(SimpleNamespace):
def __bool__(self):
return False
EMPTY = FalsyNamespace()
assert bool(EMPTY) == False

What datatype does this variable hold? [duplicate]

This question already has answers here:
What's the canonical way to check for type in Python?
(15 answers)
Closed 6 months ago.
Is there a simple way to determine if a variable is a list, dictionary, or something else?
There are two built-in functions that help you identify the type of an object. You can use type() if you need the exact type of an object, and isinstance() to check an object’s type against something. Usually, you want to use isinstance() most of the times since it is very robust and also supports type inheritance.
To get the actual type of an object, you use the built-in type() function. Passing an object as the only parameter will return the type object of that object:
>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True
This of course also works for custom types:
>>> class Test1 (object):
pass
>>> class Test2 (Test1):
pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True
Note that type() will only return the immediate type of the object, but won’t be able to tell you about type inheritance.
>>> type(b) is Test1
False
To cover that, you should use the isinstance function. This of course also works for built-in types:
>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True
isinstance() is usually the preferred way to ensure the type of an object because it will also accept derived types. So unless you actually need the type object (for whatever reason), using isinstance() is preferred over type().
The second parameter of isinstance() also accepts a tuple of types, so it’s possible to check for multiple types at once. isinstance will then return true, if the object is of any of those types:
>>> isinstance([], (tuple, list, set))
True
Use type():
>>> a = []
>>> type(a)
<type 'list'>
>>> f = ()
>>> type(f)
<type 'tuple'>
It might be more Pythonic to use a try...except block. That way, if you have a class which quacks like a list, or quacks like a dict, it will behave properly regardless of what its type really is.
To clarify, the preferred method of "telling the difference" between variable types is with something called duck typing: as long as the methods (and return types) that a variable responds to are what your subroutine expects, treat it like what you expect it to be. For example, if you have a class that overloads the bracket operators with getattr and setattr, but uses some funny internal scheme, it would be appropriate for it to behave as a dictionary if that's what it's trying to emulate.
The other problem with the type(A) is type(B) checking is that if A is a subclass of B, it evaluates to false when, programmatically, you would hope it would be true. If an object is a subclass of a list, it should work like a list: checking the type as presented in the other answer will prevent this. (isinstance will work, however).
On instances of object you also have the:
__class__
attribute. Here is a sample taken from Python 3.3 console
>>> str = "str"
>>> str.__class__
<class 'str'>
>>> i = 2
>>> i.__class__
<class 'int'>
>>> class Test():
... pass
...
>>> a = Test()
>>> a.__class__
<class '__main__.Test'>
Beware that in python 3.x and in New-Style classes (aviable optionally from Python 2.6) class and type have been merged and this can sometime lead to unexpected results. Mainly for this reason my favorite way of testing types/classes is to the isinstance built in function.
Determine the type of a Python object
Determine the type of an object with type
>>> obj = object()
>>> type(obj)
<class 'object'>
Although it works, avoid double underscore attributes like __class__ - they're not semantically public, and, while perhaps not in this case, the builtin functions usually have better behavior.
>>> obj.__class__ # avoid this!
<class 'object'>
type checking
Is there a simple way to determine if a variable is a list, dictionary, or something else? I am getting an object back that may be either type and I need to be able to tell the difference.
Well that's a different question, don't use type - use isinstance:
def foo(obj):
"""given a string with items separated by spaces,
or a list or tuple,
do something sensible
"""
if isinstance(obj, str):
obj = str.split()
return _foo_handles_only_lists_or_tuples(obj)
This covers the case where your user might be doing something clever or sensible by subclassing str - according to the principle of Liskov Substitution, you want to be able to use subclass instances without breaking your code - and isinstance supports this.
Use Abstractions
Even better, you might look for a specific Abstract Base Class from collections or numbers:
from collections import Iterable
from numbers import Number
def bar(obj):
"""does something sensible with an iterable of numbers,
or just one number
"""
if isinstance(obj, Number): # make it a 1-tuple
obj = (obj,)
if not isinstance(obj, Iterable):
raise TypeError('obj must be either a number or iterable of numbers')
return _bar_sensible_with_iterable(obj)
Or Just Don't explicitly Type-check
Or, perhaps best of all, use duck-typing, and don't explicitly type-check your code. Duck-typing supports Liskov Substitution with more elegance and less verbosity.
def baz(obj):
"""given an obj, a dict (or anything with an .items method)
do something sensible with each key-value pair
"""
for key, value in obj.items():
_baz_something_sensible(key, value)
Conclusion
Use type to actually get an instance's class.
Use isinstance to explicitly check for actual subclasses or registered abstractions.
And just avoid type-checking where it makes sense.
You can use type() or isinstance().
>>> type([]) is list
True
Be warned that you can clobber list or any other type by assigning a variable in the current scope of the same name.
>>> the_d = {}
>>> t = lambda x: "aight" if type(x) is dict else "NOPE"
>>> t(the_d) 'aight'
>>> dict = "dude."
>>> t(the_d) 'NOPE'
Above we see that dict gets reassigned to a string, therefore the test:
type({}) is dict
...fails.
To get around this and use type() more cautiously:
>>> import __builtin__
>>> the_d = {}
>>> type({}) is dict
True
>>> dict =""
>>> type({}) is dict
False
>>> type({}) is __builtin__.dict
True
be careful using isinstance
isinstance(True, bool)
True
>>> isinstance(True, int)
True
but type
type(True) == bool
True
>>> type(True) == int
False
While the questions is pretty old, I stumbled across this while finding out a proper way myself, and I think it still needs clarifying, at least for Python 2.x (did not check on Python 3, but since the issue arises with classic classes which are gone on such version, it probably doesn't matter).
Here I'm trying to answer the title's question: how can I determine the type of an arbitrary object? Other suggestions about using or not using isinstance are fine in many comments and answers, but I'm not addressing those concerns.
The main issue with the type() approach is that it doesn't work properly with old-style instances:
class One:
pass
class Two:
pass
o = One()
t = Two()
o_type = type(o)
t_type = type(t)
print "Are o and t instances of the same class?", o_type is t_type
Executing this snippet would yield:
Are o and t instances of the same class? True
Which, I argue, is not what most people would expect.
The __class__ approach is the most close to correctness, but it won't work in one crucial case: when the passed-in object is an old-style class (not an instance!), since those objects lack such attribute.
This is the smallest snippet of code I could think of that satisfies such legitimate question in a consistent fashion:
#!/usr/bin/env python
from types import ClassType
#we adopt the null object pattern in the (unlikely) case
#that __class__ is None for some strange reason
_NO_CLASS=object()
def get_object_type(obj):
obj_type = getattr(obj, "__class__", _NO_CLASS)
if obj_type is not _NO_CLASS:
return obj_type
# AFAIK the only situation where this happens is an old-style class
obj_type = type(obj)
if obj_type is not ClassType:
raise ValueError("Could not determine object '{}' type.".format(obj_type))
return obj_type
using type()
x='hello this is a string'
print(type(x))
output
<class 'str'>
to extract only the str use this
x='this is a string'
print(type(x).__name__)#you can use__name__to find class
output
str
if you use type(variable).__name__ it can be read by us
In many practical cases instead of using type or isinstance you can also use #functools.singledispatch, which is used to define generic functions (function composed of multiple functions implementing the same operation for different types).
In other words, you would want to use it when you have a code like the following:
def do_something(arg):
if isinstance(arg, int):
... # some code specific to processing integers
if isinstance(arg, str):
... # some code specific to processing strings
if isinstance(arg, list):
... # some code specific to processing lists
... # etc
Here is a small example of how it works:
from functools import singledispatch
#singledispatch
def say_type(arg):
raise NotImplementedError(f"I don't work with {type(arg)}")
#say_type.register
def _(arg: int):
print(f"{arg} is an integer")
#say_type.register
def _(arg: bool):
print(f"{arg} is a boolean")
>>> say_type(0)
0 is an integer
>>> say_type(False)
False is a boolean
>>> say_type(dict())
# long error traceback ending with:
NotImplementedError: I don't work with <class 'dict'>
Additionaly we can use abstract classes to cover several types at once:
from collections.abc import Sequence
#say_type.register
def _(arg: Sequence):
print(f"{arg} is a sequence!")
>>> say_type([0, 1, 2])
[0, 1, 2] is a sequence!
>>> say_type((1, 2, 3))
(1, 2, 3) is a sequence!
As an aside to the previous answers, it's worth mentioning the existence of collections.abc which contains several abstract base classes (ABCs) that complement duck-typing.
For example, instead of explicitly checking if something is a list with:
isinstance(my_obj, list)
you could, if you're only interested in seeing if the object you have allows getting items, use collections.abc.Sequence:
from collections.abc import Sequence
isinstance(my_obj, Sequence)
if you're strictly interested in objects that allow getting, setting and deleting items (i.e mutable sequences), you'd opt for collections.abc.MutableSequence.
Many other ABCs are defined there, Mapping for objects that can be used as maps, Iterable, Callable, et cetera. A full list of all these can be seen in the documentation for collections.abc.
value = 12
print(type(value)) # will return <class 'int'> (means integer)
or you can do something like this
value = 12
print(type(value) == int) # will return true
type() is a better solution than isinstance(), particularly for booleans:
True and False are just keywords that mean 1 and 0 in python. Thus,
isinstance(True, int)
and
isinstance(False, int)
both return True. Both booleans are an instance of an integer. type(), however, is more clever:
type(True) == int
returns False.
In general you can extract a string from object with the class name,
str_class = object.__class__.__name__
and using it for comparison,
if str_class == 'dict':
# blablabla..
elif str_class == 'customclass':
# blebleble..
For the sake of completeness, isinstance will not work for type checking of a subtype that is not an instance. While that makes perfect sense, none of the answers (including the accepted one) covers it. Use issubclass for that.
>>> class a(list):
... pass
...
>>> isinstance(a, list)
False
>>> issubclass(a, list)
True

What is a 'NoneType' object?

I'm getting this error when I run my python script:
TypeError: cannot concatenate 'str' and 'NoneType' objects
I'm pretty sure the 'str' means string, but I dont know what a 'NoneType' object is. My script craps out on the second line, I know the first one works because the commands from that line are in my asa as I would expect. At first I thought it may be because I'm using variables and user input inside send_command.
Everything in 'CAPS' are variables, everything in 'lower case' is input from 'parser.add_option' options.
I'm using pexpect, and optparse
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + group + V3AUTHCMD + snmphmac + snmpauth + PRIVCMD + snmpencrypt + snmppriv)
NoneType is the type for the None object, which is an object that indicates no value. None is the return value of functions that "don't return anything". It is also a common default return value for functions that search for something and may or may not find it; for example, it's returned by re.search when the regex doesn't match, or dict.get when the key has no entry in the dict. You cannot add None to strings or other objects.
One of your variables is None, not a string. Maybe you forgot to return in one of your functions, or maybe the user didn't provide a command-line option and optparse gave you None for that option's value. When you try to add None to a string, you get that exception:
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
One of group or SNMPGROUPCMD or V3PRIVCMD has None as its value.
For the sake of defensive programming, objects should be checked against nullity before using.
if obj is None:
or
if obj is not None:
NoneType is simply the type of the None singleton:
>>> type(None)
<type 'NoneType'>
From the latter link above:
None
The sole value of the type NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function. Assignments to None are illegal and raise a SyntaxError.
In your case, it looks like one of the items you are trying to concatenate is None, hence your error.
It means you're trying to concatenate a string with something that is None.
None is the "null" of Python, and NoneType is its type.
This code will raise the same kind of error:
>>> bar = "something"
>>> foo = None
>>> print foo + bar
TypeError: cannot concatenate 'str' and 'NoneType' objects
In Python
NoneType is the type of the None object.
There is only one such object.
Therefore, "a None object" and "the None object" and
"None" are three equivalent ways of saying the same thing.
Since all Nones are identical and not only equal,
you should prefer x is None over x == None in your code.
You will get None in many places in regular Python
code as pointed out by the accepted answer.
You will also get None in your own code when you
use the function result of a function that does not end with
return myvalue or the like.
Representation:
There is a type NoneType in some but not all versions of Python,
see below.
When you execute print(type(None)), you will get
<type 'NoneType'>.
This is produced by the __repr__ method of NoneType.
See the documentation of repr
and that of
magic functions
(or "dunder functions" for the double underscores in their names) in general.
In Python 2.7
NoneType is a type defined in the
standard library module types
In Python 3.0 to 3.9
NoneType has been
removed
from
module types,
presumably because there is only a single value of this type.
It effectively exists nevertheless, it only has no built-in name:
You can access NoneType by writing type(None).
If you want NoneType back, just define
NoneType = type(None).
In Python 3.10+
NoneType is again a type defined in the
standard library module types,
introduced in order to
help type checkers do their work
In Python, to represent the absence of a value, you can use the None value types.NoneType.None
In the error message, instead of telling you that you can't concatenate two objects by showing their values (a string and None in this example), the Python interpreter tells you this by showing the types of the objects that you tried to concatenate. The type of every string is str while the type of the single None instance is called NoneType.
You normally do not need to concern yourself with NoneType, but in this example it is necessary to know that type(None) == NoneType.
Your error's occurring due to something like this:
>>> None + "hello world"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
>>>
Python's None object is roughly equivalent to null, nil, etc. in other languages.
If you're getting type None for an object, make sure you're returning in the method. For example:
class Node:
# node definition
then,
def some_funct():
# some code
node = Node(self, self.head)
self.head = node
if you do not return anything from some_func(), the return type will be NoneType because it did not return anything.
Instead, if you return the node itself, which is a Node object, it will return the Node-object type.
def some_func(self):
node = Node(self, self.head)
self.head = node
return node
One of the variables has not been given any value, thus it is a NoneType. You'll have to look into why this is, it's probably a simple logic error on your part.
It's returned when you have for instance print as your last statement in a function instead of return:
def add(a, b):
print(a+ b)
x = add(5,5)
print(x)
print(type(x))
y = x + 545
print(y)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
<class 'NoneType'>
def add(a, b):
return (a+ b)
x = add(5,5)
print(x)
print(type(x))
10
<class 'int'>
555
NoneType is the type of None.
See the Python 2 docs here:
https://docs.python.org/2/library/types.html#types.NoneType
NoneType is type of None. Basically, The NoneType occurs for multiple reasons,
Firstly when you have a function and a condition inside (for instance), it will return None if that condition is not met.
Ex:-
def dummy(x, y): if x > y: return x res = dummy(10, 20) print(res) # Will give None as the condition doesn't meet.
To solve this return the function with 0, I.e return 0, the function will end with 0 instead of None if the condition is not satisfied.
Secondly, When you explicitly assign a variable to a built-in method, which doesn't return any value but None.
my_list = [1,2,3]
my_list = my_list.sort()
print(my_list) #None sort() mutate the DS but returns nothing if you print it.
Or
lis = None
re = lis.something())
print(re) # returns attribute error NonType object has no attribute something

Variable with name `None`

I need to have a variable with name None:
class QAbstractPrintDialog(QDialog):
None = int() # QAbstractPrintDialog.PrintDialogOption enum
PrintToFile = int() # QAbstractPrintDialog.PrintDialogOption enum
PrintSelection = int() # QAbstractPrintDialog.PrintDialogOption enum
...
But:
syntax error: cannot assign to None
I need the name to be None. I thought this will work:
QAbstractPrintDialog.None = int() # QAbstractPrintDialog.PrintDialogOption enum
But it didn't. Is there a workaround to not have a syntax error?
Solutions like setattr don't work for me - this code will be parsed to extract classes, functions, arguments, etc.
Python 2.6, 2.7
EDIT:
I am helping a guy to write pseudo-Python modules which contain description of Qt classes. QAbstractPrintDialog is one of the classes and it has enum QAbstractPrintDialog::PrintDialogOption (http://doc.trolltech.com/latest/qabstractprintdialog.html). One of the enums is None. I can easily reference a None attribute via QAbstractPrintDialog.None but i can not set it. int() means the type of the attribute.
See here: http://scummos.blogspot.com/2011/06/kdevelop-python-language-support-plugin.html
In python None is a reserved word and cannot be used as a variable name.
Quoting python documentation:
Changed in version 2.4: Assignments to None are illegal and raise a SyntaxError.
You cannot. None is a Python built-in constant.
To do what you are makes no more sense than:
class = struct
"Assignments to None are illegal and raise a SyntaxError."
--The documentation
Pick another variable name: nil, none, nothing, zilch, not_a_sausage, no_votes, zero, ...
I agree with you that this is a little inconsistent with other built-in constants, viz:
>>> class Foo:
... def __init__(self):
... self.False = True
... self.True = False
... self.None = 'Something'
...
File "<stdin>", line 5
SyntaxError: assignment to None
...but then...
>>> class Foo:
... def __init__(self):
... self.False = True
... self.True = False
...
>>> f = Foo()
>>> f.True
False
>>> f.False
True
>>> f.None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Foo instance has no attribute 'None'
...of course that kind of naming and assignment could only ever lead to trouble!
Call it something distinct like __INSTEADOF_None then strip off all instances of '_INSTEADOF' in a pre-processing step prior to parsing.
It's against the rules to assign to None which has a very special meaning in Python. Choose a different name.
You can try next approach:
>>> class A():pass
>>> a = A()
>>> a.None = 2
SyntaxError: assignment to None
>>> a.__dict__['None'] = 2
>>> a.None
2
>>> dir(a)
['None', '__doc__', '__module__']
But still - idea to use None as object field is really bad.

Finding type in python - TypeError 'unicode' object is not callable

I'm trying to make sure an object is a string type in Python (for google app engine). I'm doing this so that I can change it to a db.Text type if its more than 500 bytes. However, I keep getting the error: TypeError 'unicode' object is not callable
if type(value) in types.StringTypes and len(value) > 499:
value = db.Text(value)
setattr(entity, key, value)
What should I use to test if the type of the object is a string?
I think you just need to remove the parentheses from types.StringTypes, since it is a tuple (and not callable, hence the error). Either that, or your code is actually using StringType, which means your code is making a new string instance instead of returning the str type. Either way, it looks like a typo. See the docs.
Why are you calling types.StringTypes ? It's a tuple:
>>> types.StringTypes
(<type 'str'>, <type 'unicode'>)
Use isinstance(value, types.StringTypes) and len(value) > 499
Greg Haskins is right
>>> types.StringTypes()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
>>> types.StringTypes
(<type 'str'>, <type 'unicode'>)
Could you do
if type(variable_name) == type("")
Edit: Oops! I was looking at types.StringType, instead of types.StringTypes, so the test could be:
if type(value) in types.StringTypes and len(value) > 499:
value = db.Text(value)
Where the main problem with the OP code was the presence of the parens at the end of types.StringTypes.
Original: A few problems here:
If value holds a Unicode, testing it with type() will return types.UnicodeType
The types.StringType is a constant, not a function, so drop the parentheses.
Furthermore, types.StringType isn't iterable, so test against it with == or is.
Thus, your test could look something like:
if ((type(value) == types.StringType) or (type(value) == types.UnicodeType)) and len(value) > 499:
value = db.Text(value)
I prefer
isinstance(object_to_be_checked, str)

Categories

Resources