Using nltk.book import in a function - python

I am trying to write a simple function as follows:
def lexical_diversity(text,word):
from nltk.book import text
return 100*text.count(word)/len(set(text))
I understand that I can import a text before the function. But, I was wondering why I get the following error
ImportError: cannot import name 'text' from 'nltk.book'
It is telling me that "text" as a corpus does not exist in nltk--it is true. But, I want the user to identify the text to be text1, text2, or text3.

In order to import a submodule of a library in python, you can use importlib module.
import importlib
def lexical_diversity(nltk_sub_module,word):
imported_model_module = importlib.import_module( "nltk.book")
text = getattr(imported_model_module,nltk_sub_module)
return 100*text.count(word)/len(set(text))
lexical_diversity("text3", "book")

Related

How to monkeypatch a python library class method?

I am trying to modify a better_profanity library to include an additional argument to get_replacement_for_swear_word function. To do so I first import the necessary parts of the library and test its functionality before:
from better_profanity import profanity, Profanity
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
Now I get the source code of the class method, modify it and execute it to __main___:
from inspect import getsource
new_hide_swear_words = getsource(profanity._hide_swear_words).replace(
'get_replacement_for_swear_word(censor_char)', 'get_replacement_for_swear_word(censor_char, cur_word)').replace(
'ALLOWED_CHARACTERS', 'self.ALLOWED_CHARACTERS'
)
# fixing the indent
new_hide_swear_words = '\n'.join(i[4:] for i in new_hide_swear_words.split('\n'))
exec(new_hide_swear_words)
Now I replace this function inside the class:
profanity._hide_swear_words = _hide_swear_words.__get__(profanity, Profanity)
Note that I swap ALLOWED_CHARACTERS for self.ALLOWED_CHARACTERS. This is because the author of the library has imported ALLOWED_CHARACTERS in the same file where the class is defined, so when I swap the function and try to run the first piece of code again, it sais that this variable is not defined. It just so happens that it is stored in self as well, but there is no such luck with several other imported modules. Any ideas how to tackle this?
Here is the class definition on github.
When you run exec(new_hide_swear_words), you define the function _hide_swear_words in your current module (that's why you can access it later with just _hide_swear_words).
That however means, that the function lives fully in your module, so when you call it indirectly with profanity.censor(some_text) it will run the function inside this module and look for all dependent global symbols in your module.
That's why it can't access the variable ALLOWED_CHARACTERS or the function any_next_words_form_swear_words. They are defined in the profanity module, but not in your module where you run the exec.
One way to solve this, would be to just import all symbols into your module.
from inspect import getsource
from better_profanity import Profanity, profanity
from better_profanity.constants import ALLOWED_CHARACTERS
from better_profanity.utils import *
new_hide_swear_words = getsource(profanity._hide_swear_words)
new_hide_swear_words = "\n".join(i[4:] for i in new_hide_swear_words.split("\n"))
exec(new_hide_swear_words)
profanity._hide_swear_words = _hide_swear_words.__get__(profanity, Profanity)
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
Another way would be to execute the function in the profanity module itself (then all the symbols are already defined).
However that also has a little overhead. E.g. you have to import the module and pass it to the exec function, and afterwards you need to extract the function from the module (as it will be defined in that module).
from importlib import import_module
from inspect import getsource
from better_profanity import Profanity, profanity
new_hide_swear_words = getsource(profanity._hide_swear_words)
# fixing the indent
new_hide_swear_words = "\n".join(i[4:] for i in new_hide_swear_words.split("\n"))
profanity_module = import_module(Profanity.__module__)
exec(new_hide_swear_words, vars(profanity_module))
profanity._hide_swear_words = profanity_module._hide_swear_words.__get__(
profanity, Profanity
)
text = "Nice c0ck"
censored = profanity.censor(text)
print(censored)
profanity_module = import_module(Profanity.__module__) is the same thing as import better_profanity.better_profanity as profanity_module.

Python import class from other files

I have three files under the same directory, namely, main.py, Newtester.py, and fileUtility.py. In Newtester.py there is a class named Function. In main.py, there are the following codes:
from file.py import *
...
def main():
...
funcs = parseFuncSpec(funcInputFile)
parseFuncSpec is defined in fileUtilities.py as:
some code to import Newtester.py
def parseFuncSpec(fName):
curFunc = function(funcName, numTest, [], score)
Regardless of what I put in import Newtester.py, I always get an error saying "Function" (the class defined in the file "Newtester.py") is not defined. Following Python: How to import other Python files, I have attempted
import Newtester
__import__("Newtester")
exec("Newtester.py")
exec("Newtester")
import importlib
importlib.__import__("Newtester")
os.system("Newtester.py")
But none of them seemed to work. Any advice is appreciated. See https://github.com/r2dong/unitTesting if you are interested in seeing the complete files.
It's because you are not using it correctly
well when you use import statement like below only Newstester file is imported
import Newtester
hence instead of using parseFuncSpec() directly you have to use it as Newtester.parseFuncSpec()
or to use parseFuncSpec() directly you need to use below import statement:
from Newtester import parseFuncSpec

import file by url route python

Im trying to import files on Flask app in base of url route. I started to coding python few days ago so i havent idea if i doing it well. I write this on :
#app.route('/<file>')
def call(file):
__import__('controller.'+file)
hello = Example('Hello world')
return hello.msg
And i have other file called example.py into a controller folder that contains this:
class Example:
def __init__(self, msg):
self.msg = msg
So i start from terminal the app and i try to enter to localhost:5000/example.
Im trying to show in screen Hello world but give me the next error:
NameError: global name 'Example' is not defined
Thanks for all!
__import__ returns the newly imported module; names from that module are not added to your globals, so you need to get the Example class as an attribute from the returned module:
module = __import__('controller.'+file)
hello = module.Example('Hello world')
__import__ is rather low-level, you probably want to use importlib.import_module() instead:
import importlib
module = importlib.import_module('controller.'+file)
hello = module.Example('Hello world')
If you need to dynamically get the classname too, use getattr():
class_name = 'Example'
hello_class = getattr(module, class_name)
hello = hello_class('Hello world')
The Werkzeug package (used by Flask) offers a helpful functions here: werkzeug.utils.import_string() imports an object dynamically:
from werkzeug.utils import import_string
object_name = 'controller.{}:Example'.format(file)
hello_class = import_string(object_name)
This encapsulates the above process.
You'll need to be extremely careful with accepting names from web requests and using those as module names. Please do sanitise the file argument and only allow alphanumerics to prevent relative imports from being used.
You could use the werkzeug.utils.find_modules() function to limit the possible values for file here:
from werkzeug.utils import find_modules, import_string
module_name = 'controller.{}'.format(file)
if module_name not in set(find_modules('controller')):
abort(404) # no such module in the controller package
hello_class = import_string(module_name + ':Example')
I think you might not add the directory to the file, add the following code into the previous python program
# Add another directory
import sys
sys.path.insert(0, '/your_directory')
from Example import Example
There are two ways for you to do imports in Python:
import example
e = example.Example('hello world')
or
from example import Example
e = Example('hello world')

markdown module has no inlinepatterns attribute

I'm writing a markdown extension, but when I run it from the python command line:
>>> import markdown
>>> markdown.markdown('foo --deleted-- bar', ['myextension'])
I get the following error:
AttributeError: 'module' object has no attribute 'inlinepatterns'
On this line:
md.inlinepatterns.add('del', del_tag, '>not_strong')
I've updated markdown to 2.3.1 and I'm running it in Python 2.6. The interpreter appears to be finding my mdx_myextension.py file as the tracebook reflects that it has registered the extension.
Seems like you are referencing the attribute by the wrong name.
Use inlinePatterns instead of inlinepatterns.
See Python Markdown documentaion - extensions api
You may need to import markdown.inlinepatterns
Markdown extension code
import markdown
import markdown.inlinepatterns
DEL_RE = r'(--)(.*?)--'
class MyExtension(markdown.Extension):
def extendMarkdown(self, md, md_globals):
# Create the del pattern
del_tag = markdown.inlinepatterns.SimpleTagPattern(DEL_RE, 'del')
# Insert del pattern into markdown parser
md.inlinePatterns.add('del', del_tag, '>not_strong')
def makeExtension(configs=None):
return MyExtension(configs=configs)
Example code
import markdown
import mdx_myextension
if __name__ == "__main__":
print markdown.markdown('foo --deleted-- bar', ['myextension'])
Reference: http://achinghead.com/python-markdown-adding-insert-delete.html

how to run a code in __init__.py

In src/webprofiles/__init__.py I have
def match(string)
Now how can I make a call to this match from `src/python.py, which contains
from webprofiles import *
for x in text
a= webprofiles.match(x)
Its giving me an error
NameError: global name 'webprofiles' is not defined
When you use from import form, you must call function without module prefix.
just call the functions and attributes via their names.
from webprofiles import *
for x in text:
a= match(x)
but i suggest to DO NOT use wildcard('*') imports.
use this instead:
from webprofiles import match
for x in text:
a= match(x)
The syntax from x impoort * means that everything will be imported, in effect, into the global namespace. What you want is either import webprofiles followed by webprofiles.match or from webprofiles import * followed by a call to plain match
Just import webprofiles, not *:
import webprofiles
for x in text
a = webprofiles.match(x)
What you have there seems to me 2 files and you want to run a file which imports the methods contained in an other file:
import /webprofiles/init
init.match(x)
after modifiying your question:
import /webprofiles/__init__
__init__.match(x)
btw when you import something:
import my_file #(file.py)
my_file.quick_sort(x)
^^^^^^ you have to call myfile as you call normally an object
from my_file import *
#that is read as from my_file import everything
#so now you can use the method quick_sort() without calling my_file
quick_sort(x)

Categories

Resources