Module object is not callable when using Glob [duplicate] - python-3.x

File "C:\Users\Administrator\Documents\Mibot\oops\blinkserv.py", line 82, in __init__
self.serv = socket(AF_INET,SOCK_STREAM)
TypeError: 'module' object is not callable
Why am I getting this error?
I'm confused.
How can I solve this error?

socket is a module, containing the class socket.
You need to do socket.socket(...) or from socket import socket:
>>> import socket
>>> socket
<module 'socket' from 'C:\Python27\lib\socket.pyc'>
>>> socket.socket
<class 'socket._socketobject'>
>>>
>>> from socket import socket
>>> socket
<class 'socket._socketobject'>
This is what the error message means:
It says module object is not callable, because your code is calling a module object. A module object is the type of thing you get when you import a module. What you were trying to do is to call a class object within the module object that happens to have the same name as the module that contains it.
Here is a way to logically break down this sort of error:
"module object is not callable. Python is telling me my code trying to call something that cannot be called. What is my code trying to call?"
"The code is trying to call on socket. That should be callable! Is the variable socket is what I think it is?`
I should print out what socket is and check print(socket)

Assume that the content of YourClass.py is:
class YourClass:
# ......
If you use:
from YourClassParentDir import YourClass # means YourClass.py
In this way, you will get TypeError: 'module' object is not callable if you then tried to call YourClass().
But, if you use:
from YourClassParentDir.YourClass import YourClass # means Class YourClass
or use YourClass.YourClass(), it works.

Add to the main __init__.py in YourClassParentDir, e.g.:
from .YourClass import YourClass
Then, you will have an instance of your class ready when you import it into another script:
from YourClassParentDir import YourClass

Short answer: You are calling a file/directory as a function instead of real function
Read on:
This kind of error happens when you import module thinking it as function and call it.
So in python module is a .py file. Packages(directories) can also be considered as modules.
Let's say I have a create.py file. In that file I have a function like this:
#inside create.py
def create():
pass
Now, in another code file if I do like this:
#inside main.py file
import create
create() #here create refers to create.py , so create.create() would work here
It gives this error as am calling the create.py file as a function.
so I gotta do this:
from create import create
create() #now it works.

Here is another gotcha, that took me awhile to see even after reading these posts. I was setting up a script to call my python bin scripts. I was getting the module not callable too.
My zig was that I was doing the following:
from mypackage.bin import myscript
...
myscript(...)
when my zag needed to do the following:
from mypackage.bin.myscript import myscript
...
myscript(...)
In summary, double check your package and module nesting.
What I am trying to do is have a scripts directory that does not have the *.py extension, and still have the 'bin' modules to be in mypackage/bin and these have my *.py extension. I am new to packaging, and trying to follow the standards as I am interpreting them. So, I have at the setup root:
setup.py
scripts/
script1
mypackage/
bin/
script1.py
subpackage1/
subpackage_etc/
If this is not compliant with standard, please let me know.

It seems like what you've done is imported the socket module as import socket. Therefore socket is the module. You either need to change that line to self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM), as well as every other use of the socket module, or change the import statement to from socket import socket.
Or you've got an import socket after your from socket import *:
>>> from socket import *
>>> serv = socket(AF_INET,SOCK_STREAM)
>>> import socket
>>> serv = socket(AF_INET,SOCK_STREAM)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: 'module' object is not callable

I know this thread is a year old, but the real problem is in your working directory.
I believe that the working directory is C:\Users\Administrator\Documents\Mibot\oops\. Please check for the file named socket.py in this directory. Once you find it, rename or move it. When you import socket, socket.py from the current directory is used instead of the socket.py from Python's directory. Hope this helped. :)
Note: Never use the file names from Python's directory to save your program's file name; it will conflict with your program(s).

When configuring an console_scripts entrypoint in setup.py I found this issue existed when the endpoint was a module or package rather than a function within the module.
Traceback (most recent call last):
File "/Users/ubuntu/.virtualenvs/virtualenv/bin/mycli", line 11, in <module>
load_entry_point('my-package', 'console_scripts', 'mycli')()
TypeError: 'module' object is not callable
For example
from setuptools import setup
setup (
# ...
entry_points = {
'console_scripts': [mycli=package.module.submodule]
},
# ...
)
Should have been
from setuptools import setup
setup (
# ...
entry_points = {
'console_scripts': [mycli=package.module.submodule:main]
},
# ...
)
So that it would refer to a callable function rather than the module itself. It seems to make no difference if the module has a if __name__ == '__main__': block. This will not make the module callable.

I faced the same problem. then I tried not using
from YourClass import YourClass
I just copied the whole code of YourClass.py and run it on the main code (or current code).it solved the error

you are using the name of a module instead of the name of the class
use
import socket
and then
socket.socket(...)
its a weird thing with the module, but you can also use something like
import socket as sock
and then use
sock.socket(...)

I guess you have overridden the builtin function/variable or something else "module" by setting the global variable "module". just print the module see whats in it.

Here's a possible extra edge case that I stumbled upon and was puzzled by for a while, hope it helps someone:
In some_module/a.py:
def a():
pass
In some_module/b.py:
from . import a
def b():
a()
In some_module/__init__.py:
from .b import b
from .a import a
main.py:
from some_module import b
b()
Then because when main.py loads b, it goes via __init__.py which tries to load b.py before a.py. This means when b.py tries to load a it gets the module rather than the function - meaning you'll get the error message module object is not callable
The solution here is to swap the order in some_module/__init__.py:
from .a import a
from .b import b
Or, if this would create a circular dependency, change your file names to not match the functions, and load directly from the files rather than relying on __init__.py

I got the same error below:
TypeError: 'module' object is not callable
When calling time() to print as shown below:
import time
print(time()) # Here
So, I called time.time() as shown below:
import time
print(time.time()) # Here
Or, I imported time from time as shown below:
from time import time # Here
print(time())
Then, the error was solved:
1671301094.5742612

I had this error when I was trying to use optuna (a library for hyperparameter tuning) with LightGBM. After an hour struggle I realized that I was importing class directly and that was creating an issue.
import lightgbm as lgb
def LGB_Objective(trial):
parameters = {
'objective_type': 'regression',
'max_depth': trial.suggest_int('max_depth', 10, 60),
'boosting': trial.suggest_categorical('boosting', ['gbdt', 'rf', 'dart']),
'data_sample_strategy': 'bagging',
'num_iterations': trial.suggest_int('num_iterations', 50, 250),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 1.0),
'reg_alpha': trial.suggest_float('reg_alpha', 0.01, 1.0),
'reg_lambda': trial.suggest_float('reg_lambda', 0.01, 1.0)
}
'''.....LightGBM model....'''
model_lgb = lgb(**parameters)
model_lgb.fit(x_train, y_train)
y_pred = model_lgb.predict(x_test)
return mse(y_test, y_pred, squared=True)
study_lgb = optuna.create_study(direction='minimize', study_name='lgb_regression')
study_lgb.optimize(LGB_Objective, n_trials=200)
Here, the line model_lgb = lgb(**parameters) was trying to call the cLass itself.
When I digged into the __init__.py file in site_packages folder of LGB installation as below, I identified the module which was fit to me (I was working on regression problem). I therefore imported LGBMRegressor and replaced lgb in my code with LGBMRegressor and it started working.
You can check in your code if you are importing the entire class/directory (by mistake) or the target module within the class.
from lightgbm import LGBMRegressor
def LGB_Objective(trial):
parameters = {
'objective_type': 'regression',
'max_depth': trial.suggest_int('max_depth', 10, 60),
'boosting': trial.suggest_categorical('boosting', ['gbdt', 'rf', 'dart']),
'data_sample_strategy': 'bagging',
'num_iterations': trial.suggest_int('num_iterations', 50, 250),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 1.0),
'reg_alpha': trial.suggest_float('reg_alpha', 0.01, 1.0),
'reg_lambda': trial.suggest_float('reg_lambda', 0.01, 1.0)
}
'''.....LightGBM model....'''
model_lgb = LGBMRegressor(**parameters) #here I've changed lgb to LGBMRegressor
model_lgb.fit(x_train, y_train)
y_pred = model_lgb.predict(x_test)
return mse(y_test, y_pred, squared=True)
study_lgb = optuna.create_study(direction='minimize', study_name='lgb_regression')
study_lgb.optimize(LGB_Objective, n_trials=200)

A simple way to solve this problem is export thePYTHONPATH variable enviroment. For example, for Python 2.6 in Debian/GNU Linux:
export PYTHONPATH=/usr/lib/python2.6`
In other operating systems, you would first find the location of this module or the socket.py file.

check the import statements since a module is not callable.
In Python, everything (including functions, methods, modules, classes etc.) is an object.

Related

Custom importer to fetch files from web before execution

I'm looking at the documentation here to try and manipulate the way the import statement works. My code uses imports in all forms
import <module>
import <package.module>
from <package> import <module>
from <package.module> import <function>
from <package.module> import *
My goal is: for a certain folder, let's call it myfolder, any import for any module within myfolder (however deep in the structure) should have some preprocessing. No matter how it's imported. Preprocessing in this case is to download the python file from an internal CMS and use that instead of the one on the disk.
​
​
I understand the meta_path and path_hooks part, and I think I need to work with the path_hooks to return a FileFinder object to the built-in meta's PathFinder. Here's what I have so far:
import os, sys
class PathhookOverride():
def __init__(self, path) -> None:
"""
This will be called when PathFinder() iterates through sys.path_hooks
"""
relative_path = os.path.relpath(path, os.getcwd())
if not relative_path.startswith('myfolder'):
## We want to override only imports that have myfolder as the first part of the relative path
raise ImportError
if os.path.isdir(path):
## We know that this is a directory, we don't want to handle this
print(f'PathhookOverride: {path} is a directory')
raise ImportError
dot_separated_path = ".".join(relative_path.split(os.path.sep))
print(dot_separated_path)
## Pull file here later
cache = sys.path_importer_cache
raise ImportError ## Go to next path_hook
def change_importer():
"""Inserts the finder into the import machinery"""
sys.path_hooks.insert(0, PathhookOverride)
from myfolder.package.module import function
Expected output:
When I import my module or function using any of the above formats, I should get the path of the file being imported.
i.e., in the code snippet above, it should print the dot_separated_path:
myfolder.package.module
Actual output:
PathhookOverride: c:\test1\myfolder is a directory
PathhookOverride: c:\test1\myfolder\package is a directory
The override only catches the directories. The path of the files are never sent to the override hook.
What am I missing? Thanks.

Importing a daily changing variable name in python [duplicate]

I'm writing a Python application that takes a command as an argument, for example:
$ python myapp.py command1
I want the application to be extensible, that is, to be able to add new modules that implement new commands without having to change the main application source. The tree looks something like:
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
So I want the application to find the available command modules at runtime and execute the appropriate one.
Python defines an __import__() function, which takes a string for a module name:
__import__(name, globals=None, locals=None, fromlist=(), level=0)
The function imports the module name, potentially using the given globals and locals to determine how to interpret the name in a package context. The fromlist gives the names of objects or submodules that should be imported from the module given by name.
Source: https://docs.python.org/3/library/functions.html#__import__
So currently I have something like:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
This works just fine, I'm just wondering if there is possibly a more idiomatic way to accomplish what we are doing with this code.
Note that I specifically don't want to get in to using eggs or extension points. This is not an open-source project and I don't expect there to be "plugins". The point is to simplify the main application code and remove the need to modify it each time a new command module is added.
See also: How do I import a module given the full path?
With Python older than 2.7/3.1, that's pretty much how you do it.
For newer versions, see importlib.import_module for Python 2 and Python 3.
Or using __import__ you can import a list of modules by doing this:
>>> moduleNames = ['sys', 'os', 're', 'unittest']
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__, moduleNames)
Ripped straight from Dive Into Python.
The recommended way for Python 2.7 and 3.1 and later is to use importlib module:
importlib.import_module(name, package=None)
Import a module. The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).
e.g.
my_module = importlib.import_module('os.path')
Note: imp is deprecated since Python 3.4 in favor of importlib
As mentioned the imp module provides you loading functions:
imp.load_source(name, path)
imp.load_compiled(name, path)
I've used these before to perform something similar.
In my case I defined a specific class with defined methods that were required.
Once I loaded the module I would check if the class was in the module, and then create an instance of that class, something like this:
import imp
import os
def load_from_file(filepath):
class_inst = None
expected_class = 'MyClass'
mod_name,file_ext = os.path.splitext(os.path.split(filepath)[-1])
if file_ext.lower() == '.py':
py_mod = imp.load_source(mod_name, filepath)
elif file_ext.lower() == '.pyc':
py_mod = imp.load_compiled(mod_name, filepath)
if hasattr(py_mod, expected_class):
class_inst = getattr(py_mod, expected_class)()
return class_inst
Using importlib
Importing a source file
Here is a slightly adapted example from the documentation:
import sys
import importlib.util
file_path = 'pluginX.py'
module_name = 'pluginX'
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Verify contents of the module:
print(dir(module))
From here, module will be a module object representing the pluginX module (the same thing that would be assigned to pluginX by doing import pluginX). Thus, to call e.g. a hello function (with no parameters) defined in pluginX, use module.hello().
To get the effect "importing" functionality from the module instead, store it in the in-memory cache of loaded modules, and then do the corresponding from import:
sys.modules[module_name] = module
from pluginX import hello
hello()
Importing a package
To import a package instead, calling import_module is sufficient. Suppose there is a package folder pluginX in the current working directory; then just do
import importlib
pkg = importlib.import_module('pluginX')
# check if it's all there..
print(dir(pkg))
Use the imp module, or the more direct __import__() function.
You can use exec:
exec("import myapp.commands.%s" % command)
If you want it in your locals:
>>> mod = 'sys'
>>> locals()['my_module'] = __import__(mod)
>>> my_module.version
'2.6.6 (r266:84297, Aug 24 2010, 18:46:32) [MSC v.1500 32 bit (Intel)]'
same would work with globals()
Similar as #monkut 's solution but reusable and error tolerant described here http://stamat.wordpress.com/dynamic-module-import-in-python/:
import os
import imp
def importFromURI(uri, absl):
mod = None
if not absl:
uri = os.path.normpath(os.path.join(os.path.dirname(__file__), uri))
path, fname = os.path.split(uri)
mname, ext = os.path.splitext(fname)
if os.path.exists(os.path.join(path,mname)+'.pyc'):
try:
return imp.load_compiled(mname, uri)
except:
pass
if os.path.exists(os.path.join(path,mname)+'.py'):
try:
return imp.load_source(mname, uri)
except:
pass
return mod
The below piece worked for me:
>>>import imp;
>>>fp, pathname, description = imp.find_module("/home/test_module");
>>>test_module = imp.load_module("test_module", fp, pathname, description);
>>>print test_module.print_hello();
if you want to import in shell-script:
python -c '<above entire code in one line>'
The following worked for me:
import sys, glob
sys.path.append('/home/marc/python/importtest/modus')
fl = glob.glob('modus/*.py')
modulist = []
adapters=[]
for i in range(len(fl)):
fl[i] = fl[i].split('/')[1]
fl[i] = fl[i][0:(len(fl[i])-3)]
modulist.append(getattr(__import__(fl[i]),fl[i]))
adapters.append(modulist[i]())
It loads modules from the folder 'modus'. The modules have a single class with the same name as the module name. E.g. the file modus/modu1.py contains:
class modu1():
def __init__(self):
self.x=1
print self.x
The result is a list of dynamically loaded classes "adapters".

How to dynamically call class.function(value) in python 3

OK, so I have a string, x = module.class.test_function(value), and I want to call it and get the response. I've tried to use getattr(module.class, test_function)(value) yet it gives the error:
AttributeError: module 'module' has no attribute 'test_function'
I'm new to these things in python, how would I do this?
Given a file my_module.py:
def my_func(greeting):
print(f'{greeting} from my_func!')
You can import your function and call it normally like this:
>>> from my_module import my_func
>>> my_func('hello')
hello from my_func!
Alternatively, if you want to import the function dynamically with getattr:
>>> import my_module
>>> getattr(my_module, 'my_func')
<function my_func at 0x1086aa8c8>
>>> a_func = getattr(my_module, 'my_func')
>>> a_func('bonjour')
bonjour from my_func!
I would only recommend this style if it's required by your use case, for instance, the method name to be called not being known until runtime, methods being generated dynamically, or something like that.
A good answer that explains getattr in more detail is - Why use setattr() and getattr() built-ins? and you can find a bit more at http://effbot.org/zone/python-getattr.htm.

Using the globals argument of timeit.timeit

I am attempting to run timeit.timeit in the following class:
from contextlib import suppress
from pathlib import Path
import subprocess
from timeit import timeit
class BackupVolume():
'''
Backup a file system on a volume using tar
'''
targetFile = "bd.tar.gz"
srcPath = Path("/BulkData")
excludes = ["--exclude=VirtualBox VMs/*", # Exclude all the VM stuff
"--exclude=*.tar*"] # Exclude this tar file
#classmethod
def backupData(cls, targetPath="~"): # pylint: disable=invalid-name
'''
Runs tar to backup the data in /BulkData so we can reorganize that
volume. Deletes any old copy of the backup repository.
Parameters:
:param str targetPath: Where the backup should be created.
'''
# pylint: disable=invalid-name
tarFile\
= Path(Path(targetPath /
cls.targetFile).resolve())
with suppress(FileNotFoundError):
tarFile.unlink()
timeit('subprocess.run(["tar", "-cf", tarFile.as_posix(),'
'cls.excludes[0], cls.excludes[1], cls.srcPath.as_posix()])',
number=1, globals=something)
The problem I have is that inside timeit() it cannot interpret subprocess. I believe that the globals argument to timeit() should help but I have no idea how to specify the module namespace. Can someone show me how?
I think in your case globals = globals() in the timeit call would work.
Explanation
The globals argument specifies a namespace in which to execute the code. Due to your import of the subprocess module (outside the function, even outside the class) you can use globals(). In doing so you have access to a dictionary of the current module, you can find more info in the documentation.
Super simple example
In this example I'll expose 3 different scenarios.
Need to access globals
Need to access locals
Custom namespace
Code to follow the example:
import subprocess
from timeit import timeit
import math
class ExampleClass():
def performance_glob(self):
return timeit("subprocess.run('ls')", number = 1, globals = globals())
def performance_loc(self):
a = 69
b = 42
return timeit("a * b", number = 1, globals = locals())
def performance_mix(self):
a = 69
return timeit("math.sqrt(a)", number = 1, globals = {'math': math, 'a': a})
In performance_glob you are timing something that needs a global import, the module subprocess. If you don't pass the globals namespace you'll get an error message like this NameError: name 'subprocess' is not defined
On the contrary, if you pass globals() to the function that depends on local values performance_loc the needed variables for the timeit execution a and b won't be in the scope. That's why you can use locals()
The last one is a general scenario where you need both the local vars in the function and general imports. If you keep in mind that the parameter globals can be specified as a dictionary, you just need to provide the necessary keys, you can customize it.

python import as a variable name

I wanted to use import with a variable name. For example I wanted to do something like this
from var import my_class
I went through pythons documentation, but seems thats a little confusing. Also I seen some other posting on stack overflow that give the example of something like this
import importlib
my_module = importlib.import_module("var, my_class)
This second example does work to a certain extent. The only issue I see here var is imported but I don't see the attributes of my_class in python's namespace. How would I equate this to my original example of
from var import my_class
Here's how to use importlib (there is no need for the second parameter):
var = importlib.import_module("var")
# Now, you can use the content of the module:
var.my_class()
There is no direct programmable equivalent for from var import my_class.
Note: As #DYZ points out in the comments, this way of solving this is not recommended in favor of importlib. Leaving it here for the sake of another working solution, but the Python docs advise "Direct use of import() is also discouraged in favor of importlib.import_module()."
Do you mean that you want to import a module whose name is defined by a variable? If so, you can use the __import__ method. For example:
>>> import os
>>> os.getcwd()
'/Users/christophershroba'
>>>
>>> name_to_import = "os"
>>> variable_module = __import__(name_to_import)
>>> variable_module.getcwd()
'/Users/christophershroba'
If you also want to call a variable method of that variable module you could use the __getattribute__ method on the module to get the function, and then call it with () as normal. The line below marked "See note" is not necessary, I just include it to show that the __getattribute__ method is returning a function.
>>> name_to_import = "os"
>>> method_to_call = "getcwd"
>>> variable_module = __import__(name_to_import)
>>> variable_module.__getattribute__(method_to_call) # See note
<built-in function getcwd>
>>> variable_module.__getattribute__(method_to_call)()
'/Users/christophershroba'
More documentation available for Python 3 here or Python2 here.

Resources