This question already has answers here:
How int() object uses "==" operator without __eq__() method in python2?
(3 answers)
Closed 2 years ago.
I've got a head scratchier and it seems I'm not the only one, but is there really no solution? I find that hard to believe!
So the question is why can't I call int.__eq__ with 2 operators or i.__eq__ with one? How can I use __eq__ (and the other comparison operators) for a per item comparison for a sequence of ints?
Here's a dump from python2.7.17:
>>> i = 0
>>> type(i)
<type 'int'>
>>> i.__eq__(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__eq__'
>>> type(i).__eq__(i, 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected 1 arguments, got 2
>>> type(i).__eq__(0)
NotImplemented
But my dumo from python3.6.9 behaves itself:
>>> i = 0
>>> type(i)
<class 'int'>
>>> i.__eq__(0)
True
>>> type(i).__eq__(i, 0)
True
>>> type(i).__eq__(0) # this is not expected to work, but just for the sake of voodoo.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: expected 1 arguments, got 0
I know python2 is no longer supported but there are a few applications that only use python2 and I would like to make my code backwards compatible anyway.
So anyone out there have a solutuon for hacking the comparison magic operator methods as function calls in python2? I am sure there must be some work around.
It seems there is some information on this. I just read that python2 falls back to using cmp in some cases, while in python3 there is no cmp (or so I read). So I guess the thing to do is not use eq and ne but instead use cmp but I love some additional perspective on this
The general rule is: don't touch dunderscore methods, use functions and operators instead and those will delegate to dunderscore implementation as necessary. In your case you're looking for the == operator or the functional equivalent operator.eq.
from operator import eq
from functools import partial
print eq(1, 2)
f = partial(eq, 1)
print f(2)
Related
This question already has answers here:
Python typing for module type
(1 answer)
Check if a parameter is a Python module?
(6 answers)
Closed 2 years ago.
If I import a module in Python, then the type of the module is, unsurprisingly, module. However, I'm not sure sure how to reference this type directly. Here by "directly" I mean by writing something like module rather than taking the type of a module. For example, in the following shell interaction, I can test whether an object obj is an int by writing isinstance(obj, int), but evidently I cannot test whether obj is a module by writing isinstance(obj, module).
>>> import random
>>> type(random)
<class 'module'>
>>> isinstance(random, module)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'module' is not defined
>>> isinstance(random, 'module')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a type or tuple of types
>>> isinstance(random, type(random))
True
>>> isinstance(1, int)
True
>>> isinstance('Hello, World!', str)
True
I don't exactly know how I whiffed this, but at some point I input
repr = 64
into the python console in spyder. When I now try to run repr(b64) this happens:
repr(b64)
Traceback (most recent call last):
File "<ipython-input-23-8c64b01419a6>", line 1, in <module>
repr(b64)
TypeError: 'int' object is not callable
can I fix this without restarting spyder?
Delete your variable:
del repr
This will clear the binding you created, unhiding the builtin. (It will not remove the builtin repr.) This gets you back to a slightly cleaner state than repr = builtins.repr would, though it usually won't matter.
Use builtins.repr:
>>> repr = 42
>>> repr(42)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> from builtins import repr
>>> repr(42)
'42'
(or use del as suggested by user2357112).
This question already has an answer here:
Builtin function not working with Spyder
(1 answer)
Closed 4 years ago.
I have been trying to use str() function to convert the integer to string in Spyder (python 2.7). Every time I got TypeError: 'str' object is not callable
For example, I wrote this simple code to test it and I got the same error:
x = 5
print str(x)
Can someone help me in this
You have overwritten the built-in str somewhere in your code.
>>> str = 'foo' # overwriting the builtin `str`
>>> x = 5
>>> print str(x) # equivalent to 'foo'(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
I have just seen the following example in PEP 484:
def greeting(name: str) -> str:
return 'Hello ' + name
print(greeting('Martin'))
print(greeting(1))
As expected, this does not work in Python 2:
File "test.py", line 1
def greeting(name: str) -> str:
^
SyntaxError: invalid syntax
However, it works for Python 3:
Hello Martin
Traceback (most recent call last):
File "test.py", line 5, in <module>
print(greeting(1))
File "test.py", line 2, in greeting
return 'Hello ' + name
TypeError: Can't convert 'int' object to str implicitly
This was unexpected. It does not really check types yet, as you can see with the following example (it runs, but does not throw an exception):
def greeting(name: str) -> int:
return 'Hello ' + name
print(greeting('Martin'))
It seems as if after the : has to be the name of a function, but the function seems to be ignored:
def aha(something):
print("aha")
return something+"!"
def greeting(name: aha, foo) -> int:
return 'Hello ' + name + foo
print(greeting('Martin', 'ad'))
The same seems to be true for the name after ->.
Is this type hinting syntax using something else (like Java Modeling language makes use of comments)? When was this syntax introduced to Python? Is there a way to do static type checking already with this Syntax? Does it always break Python 2 compatibility?
There is no type hinting going on here. All you did was provide annotations; these were introduced with PEP 3107 (only in Python 3, there is no support for this in Python 2); they let you annotate arguments and return values with arbitrary information for later inspection:
>>> greeting.__annotations__
{'name': <class 'str'>, 'return': <class 'str'>}
They are otherwise not consulted at all here. Instead, the error message you got is from trying to concatenate string and integer values in the body of the function:
>>> 'Hello ' + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
It is a custom type error aimed at providing additional information as to why the str + int concatenation failed; it is thrown by the str.__add__ method for any type that is not str:
>>> ''.__add__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly
>>> ''.__add__(True)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'bool' object to str implicitly
PEP 484 then proposes to make use of those annotations to do actual static type checking with additional tools, but as the introduction of the PEP states:
While these annotations are available at runtime through the usual __annotations__ attribute, no type checking happens at runtime. Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily. Essentially, such a type checker acts as a very powerful linter.
Emphasis in the original.
The PEP was inspired by existing tools that use PEP 3107 annotations; specifically the mypy project (which is looping right back by adopting PEP 484), but also the type hinting support in the PyCharm IDE and the pytypedecl project. See Guido van Rossum's original email kickstarting this effort as well as a follow-up email.
mypy apparently supports Python 2 by preprocessing the annotations, removing them before byte-compiling the source code for you, but you otherwise cannot normally use the syntax Python code meant to work in Python 2.
PEP 484 also describes the use of stub files, which sit next to the regular Python files; these use the .pyi extension and only contain the signatures (with type hints), leaving the main .py files annotation free and thus usable on Python 2 (provided you wrote Polyglot Python code otherwise).
I had an interesting (potentially stupid) idea: What happens if I use a built-in function name as a variable to assign some object (say integer). Here's what I tried:
>>> a = [1,2,3,4]
>>> len(a)
4
>>> len = 1
>>> len(a)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'int' object is not callable
Seems like python does not treat function and variable names differently. Without restarting the python interpreter, is there a way to assign len back to the function? Or undo the assignment len = 1?
Use del len:
>>> a=[1,2,3,4]
>>> len=15
>>> len(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> del len
>>> len(a)
4
From docs.python.org:
Deletion of a name removes the binding of that name from the local or global namespace, depending on whether the name occurs in a global statement in the same code block. If the name is unbound, a NameError exception will be raised
Technically you can get it back from __builtin__
from __builtin__ import len
But please don't name stuff len, it makes sensible programmers angry.
Okay, for a start don't name your variable after the builtins, secondly if you want to respect other functions then respect namespaces for example
import time
time.asctime()
asctime = 4253
time.asctime() # Notice that asctime here is unaffected as its inside the time module(s) namespace