Import a class with a string [duplicate] - python

This question already has answers here:
import module from string variable
(7 answers)
Closed 3 years ago.
Given dot-notation of a python class, how would I import it if it's given as a string?
For example:
>>> from ingest.models import ItemInstance
>>> ItemInstance
<class 'ingest.models.ItemInstance'>
Given the string, 'ingest.models.ItemInstance', how would I import that?
Note: the above referenced duplicated is primarily about importing a module. Here I'm looking to specifically import a class. For example:
s = "ingest.models.ItemInstance"
cls = s.split('.')[-1] # works with the given path, but not always
module = '.'.join(s.split('.')[:-1])
getattr(importlib.import_module(module), cls)
The answer provided below addresses this accurately.

In Python 2.7 and Python 3.1 or later, you can use importlib:
import importlib
i = importlib.import_module("module_name")
If you want to access the class, you can use getattr:
import importlib
module = importlib.import_module("module_name")
class_ = getattr(module, class_name)
instance = class_()

Related

Is there a way to use " from math import * " in a function? [duplicate]

This question already has answers here:
Python: Why should 'from <module> import *' be prohibited?
(6 answers)
Closed 5 months ago.
def mathImport():
from math import *
I dont know if it is possible and if it isn't, is there a other way to do something like this?
There is no way to use *-imports in nested scopes – i.e. functions or classes. Since variable scope outside of the module global namespace is determined at compile time, the runtime name-binding of *-imports does not work.
7.11. The import statement
The wild card form of import — from module import * — is only allowed at the module level. Attempting to use it in class or function definitions will raise a SyntaxError.
Explicitly import the names needed:
def mathImport():
from math import ceil
...
Instead of importing everything, just bring in what you need
def myfunction():
from math import pi, tan
# work with imports
According to Python import docs the use of from module import * is a wild card form and is not allowed to be used in class or function definition. In addition, it isn't a good practice to use this syntax, see this documentation to understand the risks.
you cannot import modules in a function and use them globally, you also cannot import from a string.
There is a module called import lib that you could use to programmatically import modules by string.
https://docs.python.org/3/library/importlib.html#module-importlib
>>> module = importlib.import_module("time", ".*")
>>> module.time()
1619787987.921014
>>>

NLTK function from string variable isn't callable [duplicate]

This question already has answers here:
import module from string variable
(7 answers)
How can I import a module dynamically given its name as string?
(10 answers)
Closed 5 years ago.
I have a list of related function names which I want to iterate thru, calling the function held in the variable. But no matter how I try it, I get: "TypeError: 'TweetTokenizer' object is not callable"
Following the solution in Calling a function of a module from a string with the function's name in Python (of which it is suggested this question is a duplicate), finds the functions in the nltk module and assigns them. But my resulting "tok_alg" function is still failing as not callable. Any advice on why this is happening would be appreciated.
#!/usr/bin/env python
import nltk
import os
testTxt="I'll have a Bloomin' Onion."
Tokenizers = [ 'Tweet', 'MWE', 'TreebankWord' ]
for tokenizer in Tokenizers:
tokz = tokenizer + 'Tokenizer'
tok_alg = getattr(nltk, tokz)()
result = tok_alg(testTxt)
print(result)
Listing the functions does work, viz
for tokenizer in [ TweetTokenizer(), MWETokenizer() ]:
result = tokenizer.tokenize(testTxt)
But the suggested conversion of str variables via getattr() is not working for NLTK. While this is elegant and practical, I need the string variables for other purposes. Surely there is some way to vivify these into a function call. What am I missing?

dynamic execute a function by a string like 'module.function' [duplicate]

This question already has answers here:
Python function pointer
(8 answers)
Closed 9 years ago.
if I have a string like 'module.function', How can I execute function just by one step?
likesomefunction('os.error','args')
You can dynamically get the modules using sys.modules and then you can use getattr to get the attributes from the module, like this
import sys
func = "os.error"
module, function = func.split(".", 1)
getattr(sys.modules[module], function)()
sys.modules can give only the modules which are already loaded. So, if you want to load a module dynamically you can use __import__ function like this
For example,
module, function = "math.factorial".split(".", 1)
print getattr(__import__(module), function)(5)
Output
120
All you need to do is
from module import function
and you'll be able to call
function(x, y, z)
in your code.

Python __import__ is only giving me top level module [duplicate]

This question already has answers here:
How can I import a module dynamically given its name as string?
(10 answers)
Closed 9 years ago.
I'm doing
module = __import__("client.elements.gui.button", globals(), locals(), [], 0)
But it's only returning client.
What is my problem?
That's what __import__ does.
When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name.
You're not really supposed to use __import__; if you want to import a module dynamically, use importlib.import_module.
Accepted answer is correct, but if you read on in the docs you'll find that this can be gotten around with an admittedly unsettling "hack" by using __import__ like so:
module = __import__('client.elements.gui.button', fromlist=[''])
It doesn't really matter what you pass in for fromlist so long as it's a non-empty list. This signals to the default __import__ implementation that you want to do a from x.y.z import foo style import, and it will return the the module you're after.
As stated you should use importlib instead, but this is still a workaround if you need to support Python versions < 2.7.
It only obtains the top level, but you can also work around this like so:
module_name = 'some.module.import.class'
module = __import__(module_name)
for n in module_name.split('.')[1:]:
module = getattr(module, n)
# module is now equal to what would normally
# have been retrieved where you to properly import the file

How to make from var_str import var_str in python [duplicate]

This question already has answers here:
How can I import a module dynamically given its name as string?
(10 answers)
Closed 8 years ago.
Let me explain..
I want to do this:
a = "somedir.somefile"
b = "someclass"
from a import b
Well, I want to do this to import automatic all classes inside a directory, and I don't know how many classes are there.
a = "somedir.somefile"
b = "someclass"
module = __import__(a, globals(), locals(), [b], -1)
clazz = getattr(module, b)
now you can do this:
instance = clazz()
instance.method()
You need the __import__ built-in function. It's a bit fiddly to use, though, because it returns the top-level module, rather than the leaf of the path. Something like this should work:
from operator import attrgetter
module_path = 'a.b.c'
class_name = 'd'
module = __import__(module_path)
attribute_path = module_path.split('.') + [class_name]
# drop the top-level name
attribute_path = attribute_path[1:]
klass = attrgetter('.'.join(attribute_path))(module)
I think what you actually want to do is use __init__.py and __all__. Take a look at the modules tutorial for details.
Alternatively, there's exec. It will do what you're asking, but is probably not the best way to get there.

Categories

Resources