A solution to monkey patch any python module [duplicate] - python

This question already has answers here:
Monkey patching a class in another module in Python
(6 answers)
Closed 7 years ago.
I am in search for the right approach to monkey patch any function in a python module from within my app without modifying the modules package itself.
The background of my question is that my app is using Elasticsearch 2. ES 2 does not accept indexing of documents where fieldnames contain periods. Since my app uses pyes in multiple locations, I'd like to globally patch the indexing method and make sure that any period characters will be turned to underscore characters.

One of the best solution is using wrapper. Create a module and use the same name you want to patch, then in your sources use from mymodule import ES.
In this way, all requests comes to your module and you can decide to run the original or modify it.
another solution is patch in each step:
from pyes import ES
real_create_index = ES.indices.create_index
def create_index(self, idx_name):
# do what you need
real_create_index(self, idx_name)
ES.indices.create_index = create_index
from now on, whoever call conn.indices.create_index it will redirect to your code.

Related

How to "type" random package return [duplicate]

This question already has an answer here:
What is the type hint for a (any) python module?
(1 answer)
Closed 2 years ago.
I'm building an API to allow for plugins in an application I'm working on. I'm using importlib.import_module to import the plugins. Clearly I have no idea what modules are going to be imported ahead of time. Is there a way to identify the return type as a generic module on the method I'm using to do the imports?
def import_plugin(plugin_name: str) -> <Some generic module type>:
# conditional tests here...
return importlib.import_module("plugins.{}".format(plugin_name))
The type of a module is given by types.ModuleType in the types module.
import types
type(types) is types.ModuleType
# => True
Python uses duck typing, so I recommend assuming it is a module, and if it is not let the user handle it. If you really want to get the type, use types.ModuleType as khelwood said.

Where is the right place to import libraries in an OOP code [duplicate]

This question already has answers here:
Should import statements always be at the top of a module?
(22 answers)
Closed 3 years ago.
let's say that I have a python file for some task written in OOP.
some classes in my code use libraries such as pandas, csv ...
Is it ok to import these libraries just before the main() function?
Technically it works but I'm not sure if this is the right way
class A
class B
class C
import csv
import pandas
def main ():
#pass
if __name__ == '__main__':
main()
PEP8 specifically describes where imports should go. Best to follow that.
Imports are always put at the top of the file, just after any module comments and docstrings, and before module globals and constants.
EDIT TO ADD: You asked about import placement when programming OOP code. Assuming you're referring to Object Oriented Programming, that is a design pattern and has no bearing on the proper placement of imports. Imports are kept at the top of the module file to make it easy for anyone to easily see what dependencies a module has.
So, even if - to use your example - classes A, B, and C don't use csv or pandas, you'd still put those at the top because the module uses them even if some specific classes don't.

How to distinguish between two methods of same name in two modules but when used in one file [duplicate]

This question already has answers here:
Python: How to import, from two modules, Classes that have same names?
(2 answers)
Closed 6 years ago.
I have a function with name 'add_member_address' at two places but with different functionalities.
First method is given below which is defined in a view.
#login_required(login_url='/accounts/login/')
def add_member_address(request, member_id):
if request.method == "GET":
pass
else:
data = request.POST
add_member_address(data, member_id) #<-this method is defined in another file.
Now when flow reaches inner add_member_address, it tries to call this outer method only. So I tried giving the full path of this inner method to distinguish.
tenant.services.address_services.add_member_address(data, member_id)
where tenant is name of my app which is already registered in settings file. But now this error is thrown.
name 'tenant' is not defined
Folder structure:
project
->tenant
->services
-> __init__.py
-> address_services.py
-> here is this add_member_address(data, member_id) method
-> other_services.py
->views
->members.py
->here is this add_member_address(request, member_id) method
inside service/__init__.py file, all services are imported as below
from .address_services import *
from .tag_services import *
Please suggest me
1. how can I distinguish between two methods of same name but in two different modules when used in same file.
2. How to use method with full path instead of importing on top of file.
Just rename one, or import only the module and look up the function as an attribute on that.
You can rename an imported name right in the import statement:
from .address_services import add_member_address as add_address
# use add_address(data, member_id)
Using the module name instead:
from . import address_services
# use address_services.add_member_address(data, member_id)
If you find the latter too verbose, remember you can rename the module reference too:
from . import address_services as as_
# use as_.add_member_address(data, member_id)
Importing everything is anyway not a good practice.
from .address_services import add_member_address as add_member_address_address_services
from .tag_services import add_member_address as add_member_address_tag_services
Or something similar.

Python static class or functions in modules [duplicate]

This question already has answers here:
python - should I use static methods or top-level functions
(5 answers)
Closed 6 years ago.
I need something to organize some utilty functions.
Variant 1.
create module and write all functions in this module.
Variant 2.
(since python has no staticclass)
create class with only static methods in main module
In general, there is no big difference.Like :
var 1)
import functionsmodule
workers = functionmodule.get_all_workers(**kwargs)
var 2)
workers = FunctionClass.get_all_workers(**kwargs)
I like the second one though.
Questions is : what is best way to do such organization ?
You could also do:
from functionsmodule import get_all_workers, some_other_method
workers = get_all_workers(**kwargs)
After a couple of months learning python, this is my preferred solution. It cleans up the code without the need to reference a class or module. I'd only recommend this if your utilities method names WONT clash with builtins or other functions
I'd usually organise these re-usable/utilities within a common package and implement something like:
from common.functions import get_all_workers, some_other_method
workers = get_all_workers(**kwargs)
EDIT: Based on your "get_all_workers" method name - I'd imagine this should go into some sort of persistence/worker class rather than a general utilities class

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

Categories

Resources