Why am I getting a 'module' object not callable in python 3?

First, all relevant codes

main.py

import string import app group1=[ "spc", "bspc",",","."]#letters, space, backspace(spans mult layers) # add in letters one at a time for s in string.ascii_lowercase: group1.append(s) group2=[0,1,2,3,4,5,6,7,8,9, "tab ","ent","lAR" ,"rAR" , "uAR", "dAR"] group3= [] for s in string.punctuation: group3.append(s)#punc(spans mult layers) group4=["copy","cut","paste","save","print","cmdW","quit","alf","sWDW"] #kb shortcut masterGroup=[group1,group2,group3,group4] myApp =app({"testFKey":[3,2,2]}) 

app.py

 import tkinter as tk import static_keys import dynamic_keys import key_labels class app(tk.Frame): def __init__(inputDict,self, master=None,): tk.Frame.__init__(self, master) self.grid(sticky=tk.N+tk.S+tk.E+tk.W) self.createWidgets(self, inputDict) def createWidgets(self,inDict): top=self.winfo_toplevel() top.rowconfigure(0, weight=1) top.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) self.columnconfigure(0, weight=1) tempDict = {} for k,v in inDict.items(): if 1<=v[0]<=3: tempDict[k] = static_keys(*v[1:]) elif v[0] ==4: tempDict[k] = dynamic_keys(k,*v[1:]) elif v[0]==5: tempDict[k] = key_labels(*v[1:]) for o in tempDict: tempDict[o].grid() return tempDict 

static_keys.py

 import tkinter class static_keys(tkinter.Label): """class for all keys that just are initiated then do nothing there are 3 options 1= modifier (shift etc) 2 = layer 3 = fkey, eject/esc""" def __init__(t,selector,r,c,parent,self ): if selector == 1: tkinter.Label.__init__(master=parent, row=r, column=c, text= t, bg ='#676731') if selector == 2: tkinter.Label.__init__(master=parent, row=r, column=c, text= t, bg ='#1A6837') if selector == 3: tkinter.Label.__init__(master=parent, row=r, column=c, text= t, bg ='#6B6966') 

Now to describe the problem. When I run main.py in python3, I get an error

 File "Desktop/kblMaker/main.py", line 13, in <module> myApp =app({"testFKey":[3,2,2]}) TypeError: 'module' object is not callable 
+4
source share
3 answers

You have a module called app that contains a class called app . If you just execute the import app in main.py, then the app will refer to the module, and app.app will refer to the class. Here are a few options:

  • Leave your import statement yourself and use myApp = app.app({"testFKey":[3,2,2]}) inside main.py
  • Replace import app with from app import app , now the app will refer to the class, and myApp = app({"testFKey":[3,2,2]}) will work fine
+9
source

In main.py change the second line to:

 from app import app 

The problem is that it has an app and app module in it. But you are importing a module, not a class from it:

 myApp = app({"testFKey": [3, 2, 2]}) 

(instead, you can replace the " app " string with " app.app " instead of " app ")

+3
source

The problem, as both FJ and Tadeck have already explained, is that app is the app module, and app.app is the app class defined in this module.

You can get around this by using from app import app (or, if necessary, even from app import * ), as in Tadeck's answer, or explicitly referring to app.app instead of just app , as in FJ's answer.

If you rename the class to app , this will not fix anything - you still have to either from app import app or access app.app , but this will make the problem much more obvious. And make your code less confusing after you fix the problem.

This is part of the reason why PEP 8 recommends:

Modules must have short, all lowercase names.

...

Almost without exception, class names use the CapWords convention.

Thus, there is no way to mix them.

+1
source

Source: https://habr.com/ru/post/1495428/


All Articles