Python 3 and isinstance(np.int64(42), int)
Hi! I just finished porting a large code-base to Python 3 (making it work on 2.6, 2.7 and 3.4). It wasn't that difficult, but one thing gave me a hard time and it was this: Python 2.7.9 (default, Apr 2 2015, 15:33:21) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information.
a = np.zeros(7, int) n = a[3] type(n) <type 'numpy.int64'> isinstance(n, int) True
With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int). So, I did this instead: import numbers isinstance(n, numbers.Integral) which works fine (with numpy-1.9). Is this the "correct" way or is there a better way to do it? I would imagine that a lot of code will break because of this - so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable). Jens Jørgen
On Wed, Jun 17, 2015 at 10:53 PM, Jens Jørgen Mortensen <jensj@fysik.dtu.dk> wrote:
type(n) <type 'numpy.int64'> isinstance(n, int) True
With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int).
Yep, that's correct.
So, I did this instead:
import numbers isinstance(n, numbers.Integral)
which works fine (with numpy-1.9). Is this the "correct" way or is there a better way to do it?
That's the correct way to check whether an arbitrary object is of some integer-like-type, yes :-). There are alternatives, and there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward, but that's a more general issue that it's hard to comment on here without more detail about what exactly you're trying to accomplish.
I would imagine that a lot of code will break because of this - so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable).
It's not possible, unfortunately. In py2, 'int' is a 32- or 64-bit integer type, so we can arrange for numpy's int32 or int64 objects to be laid out the same in memory, so everything in python that expects an int (including C API functions) can handle a numpy int. In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation. -n -- Nathaniel J. Smith -- http://vorpus.org
In some cases calling operator.index(n) may yield the desired result. I like operator.index, but maybe it is just me :). That uses duck typing instead of instance checking to ask if it represents an integer. But it also has some awkward corner cases in numpy, since arrays with a single element (deprecation pending) and 0D arrays (will continue) say they are integers when asked that way. - Sebastian On Mi, 2015-06-17 at 23:13 -0700, Nathaniel Smith wrote:
On Wed, Jun 17, 2015 at 10:53 PM, Jens Jørgen Mortensen <jensj@fysik.dtu.dk> wrote:
type(n) <type 'numpy.int64'> isinstance(n, int) True
With Python 3.4 you get False. I think I understand why (np.int64 is no longer a subclass of int).
Yep, that's correct.
So, I did this instead:
import numbers isinstance(n, numbers.Integral)
which works fine (with numpy-1.9). Is this the "correct" way or is there a better way to do it?
That's the correct way to check whether an arbitrary object is of some integer-like-type, yes :-). There are alternatives, and there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward, but that's a more general issue that it's hard to comment on here without more detail about what exactly you're trying to accomplish.
I would imagine that a lot of code will break because of this - so it would be nice if isinstance(n, int) could be made to work the same way in 2 and 3, but I don't know if this is possible (or desirable).
It's not possible, unfortunately. In py2, 'int' is a 32- or 64-bit integer type, so we can arrange for numpy's int32 or int64 objects to be laid out the same in memory, so everything in python that expects an int (including C API functions) can handle a numpy int. In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation.
-n
Nathaniel Smith <njs@pobox.com> wrote:
In py3, 'int' is an arbitrary width integer bignum, like py2 'long', which is fundamentally different from int32 and int64 in both semantics and implementation.
Only when stored in an ndarray. An array scalar object does not need to care about the exact number of bits used for storage as long as the storage is large enough, which a python int always is. Sturla
On Wed, Jun 17, 2015 at 11:13 PM, Nathaniel Smith <njs@pobox.com> wrote:
there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward,
I tend to agree with that. On the other hand, numpy itself is kind-of sort-of statically typed. But in that case, if you need to know the type of an array -- check the array's dtype. Also:
a = np.zeros(7, int) n = a[3] type(n) <type 'numpy.int64'>
I Never liked declaring numpy arrays with the python types like "int" or "float" -- in numpy you usually care more about the type, so should simple use "int64" if you want a 64 bit int. And "float64" if you want a 64 bit float. Granted, pyton floats have always been float64 (on all platfroms??), and python ints used to a be a reasonable int type, but now that python ints are bigInts in py3, it really makes sense to be clear. And now that I think about it, in py2, int is 32 bit on win64 and 64 bit on *nix64 -- so you're really better off being explicit with your numpy arrays. -CHB -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
On Fri, Jun 19, 2015 at 4:15 PM, Chris Barker <chris.barker@noaa.gov> wrote:
On Wed, Jun 17, 2015 at 11:13 PM, Nathaniel Smith <njs@pobox.com> wrote:
there's some argument that in Python, doing explicit type checks like this is usually a sign that one is doing something awkward,
I tend to agree with that.
On the other hand, numpy itself is kind-of sort-of statically typed. But in that case, if you need to know the type of an array -- check the array's dtype.
Also:
a = np.zeros(7, int) n = a[3] type(n) <type 'numpy.int64'>
I Never liked declaring numpy arrays with the python types like "int" or "float" -- in numpy you usually care more about the type, so should simple use "int64" if you want a 64 bit int. And "float64" if you want a 64 bit float. Granted, pyton floats have always been float64 (on all platfroms??), and python ints used to a be a reasonable int type, but now that python ints are bigInts in py3, it really makes sense to be clear.
And now that I think about it, in py2, int is 32 bit on win64 and 64 bit on *nix64 -- so you're really better off being explicit with your numpy arrays.
a = np.zeros(7, int) a.dtype
being late checking some examples dtype('int32')
np.__version__ '1.9.2rc1' type(a[3]) <class 'numpy.int32'>
a = np.zeros(7, int) a = np.array([888888888888888888]) a array([888888888888888888], dtype=int64)
a = np.array([888888888888888888888888888888888]) a array([888888888888888888888888888888888], dtype=object)
a = np.array([888888888888888888888888888888888], dtype=int) Traceback (most recent call last): File "<pyshell#10>", line 1, in <module> a = np.array([888888888888888888888888888888888], dtype=int) OverflowError: Python int too large to convert to C long
Looks like we need to be a bit more careful now. Josef Python 3.4.3
-CHB
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
participants (6)
-
Chris Barker
-
Jens Jørgen Mortensen
-
josef.pktd@gmail.com
-
Nathaniel Smith
-
Sebastian Berg
-
Sturla Molden