Lamoule74 Lamoule74 - 6 months ago 33
Python Question

My class is callable at the begining of my code, but not while my tests loops

I've got 2 files : main.py and batsol.py

batsol.py contains a class and main.py is creating some instances from the class Batsol.
So I'll show you a concise version of my code...

class Batsol:
def __init__(self, addressCan = None, name = None) :
self.addressCan = addressCan
self.name = name
#other stuff ...


Then my main.py :

from batsol import Batsol
# other import and code ...

print(callable(Batsol))
bs1 = Batsol()
# code...
if len(listener.ring_buffer) == 0 :
for Batsol in tab_BS :
try:
print(tab_BS[Batsol])
except (IndexError):
pass
# code...
while(True) :
# for and if interlocked
print(callable(Batsol))
bs2 = Batsol()


The console shows :

True
False
Traceback (most recent call last):
File "./main.py", line 135, in <module>
bs2 = Batsol()
TypeError: 'int' object is not callable


the second part of the traceback is not linked to other stuff i'm doing in my code (thread not terminated properly... something like this) , in my opinion

Exception ignored in: <module 'threading' from '/usr/lib/python3.4/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.4/threading.py", line 1292, in _shutdown
t = _pickSomeNonDaemonThread()
File "/usr/lib/python3.4/threading.py", line 1300, in _pickSomeNonDaemonThread
if not t.daemon and t.is_alive():
TypeError: 'bool' object is not callable


WHY my object is not callable inside my tests loops ???
It drives me crazy...

Answer

Your shadowing occurs in this code fragment:

if len(listener.ring_buffer) == 0 :
    for Batsol in tab_BS :
        try:
            print(tab_BS[Batsol])
        except (IndexError):
            pass
time.sleep(4)

for-in construct on sequences works as following:

  1. Sequence is asked for next (first, second, ... last) element. Internal pointer keeps track of element in current iteration.
  2. Element gets assigned to name on left side of "in".
  3. Go to 1.

After loop finishes, Batsol is no longer your class, but last element from tab_BS.

I'd suggest getting a better IDE, or using good static code analysis tool (Pylint / Flake8 etc.) as this kind of error is easily detected by e.g. PyCharm (your code shadows name from outer scope).

Related: How bad is shadowing names defined in outer scopes?