How to override a function in a package? - python-3.x

I am using a package from biopython called SubsMat, I want to override a function that is located in SubsMats __init__.py.
I tried making a class that inherits SubsMat like this:
from Bio import SubsMat
class MyOwnSubsMat(SubsMat):
but you cannot inherit a package I guess. I cannot alter the source code literally since it is a public package on the network.
Is there any workaround for a noob like me?

You can do that:
from Bio import SubsMat
SubsMat.function = my_own_replacement_for_function
But it will change the package for everyone using it.

Related

Which extension contains the class ModelSavingExceptionTranslationHandler?

I need to create a new class which extends ModelSavingExceptionTranslationHandler.
When I try to write it as:
import
de.hybris.platform.platformbackoffice.services.handlers.ModelSavingExceptionTranslationHandler;
I want to know which extension does it belong to so that I configure this in extensioninfo.xml.When I configure platformbackoffice, this is still not resolved.
You can find it with IDE features. For example in IntelliJ, press Select Opened File (Alt+Shift+1, 1) button after finding class.
ModelSavingExceptionTranslationHandler class in in the platformbackoffice extenison.

Python: how to write a function which depends on external modules

If we write a function which depends on some packages / modules, do we need to import all the modules from within function? Or do we somehow (how?) check for dependencies and raise an error / warning? How to do it in efficient manner as the function might be called many-many times? And how do we deal with aliases? I mean if the code that calls the function has imported a required package but used an alias, e.g. import numpy as np, how do we access it from within the function?
So looking at your comment I would suggest you have answered your own question. You understand that you don’t expect the user to know about a function’s module dependencies.
You say you want to have this function in a module - let’s call it my_module for now.
So you have a file my_module.py:
#Add any imports code in this module relies on
import os
import numpy as np
def my_numpy_func(arg1, arg2):
#function code using numpy e.g.
my_arr = np.array(arg1)
#etc etc
return result
def some_other_func():
#blah blah blah
Now anyone who wants to use your function can simply write from my_module import my_numpy_func and not have to worry about loading the dependencies.
Note: this doesn’t have anything to do with ensuring that a user actually has required non-standard packages installed on their machine. For example if they have not installed numpy they will get an ImportError when they try to import your function.
If you want to distribute your code and make it so that users don’t need to worry about that, then you probably need to make your code a package that makes the dependencies a requirement on installation.

How can I set up an alias for imports in Python?

I want my project to work in two different situations. It should work as a standalone library, but also as sub package of a larger project. The main use case is that of a standalone library, where its internal imports should be of the form
from my_library import sub_package
When using the code as sub package of a larger project, these imports don't work as there is no global name my_library. Instead, I would have to use relative or absolute imports, for example
from large_project.my_library import sub_package
Let's assume I wrote my library as shown in the first example. How can I overwrite importing behavior when running as part of a larger project to automatically adjust import paths?
Thanks to #MatrixTai's suggestion of adding the parent directory of the package to the the module path, I came up with this dynamic solution. At the top of my_library/__init__.py:
# Make package global even if used as a sub package to enable short imports.
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
We have to navigate up two directories here to do from the my_library/__init__.py to my_library and from there to its parent direction, where imports will find the library.
You don't have much choice.
If you want to reference the my_library.py anywhere, there is 2 method (as I known) can do similar work.
1: add system path. Like those module you installed by pip. pip module is installed in /Python/Scripts. You can add a new path or simply put my_library.py into one of the path. For adding, that's in Computer(right-click)-> Properties -> Environment Variable -> Choose Path and Click Edit
(Though you may not want to use this.)
2: Changing __init__.py, but still at least one line you must add in my_library.py.
For example,
/Directory
/large_project
-__init__.py #call this sub_init
-my_library.py
-__init__.py #call this main_init, this fake
-main.py
In main_init,
import sys
sys.path.append('\\Directory\\large_project')
As main_init is not executed when you execute main.py (this is fake), so in main.py
import __init__
from my_library import sub_package
But as well you can take this main_init as the starter of library, like declaring __all__, etc.

does an imported function from a module could access class from this module?

I am a new comer when it comes to package and module to python.
I am trying to cut my script in several separate compartiment. to improve readability and maintenance.
My problem is the following:
I have a module which define a class and a function inside this module which instantiate this class.
module blast.py
class Blast():
blabla
def foo():
blast = Blast()
# do some stuff
this module is inside a package with a _ _init__.py file
__all__ = ["blast"]
I have a main script In which i want to use that function.
I import the module with
from package import blast
But To use that function I have to use the name space of the module ( at least my IDE say me that: pycharm)
blast.foo()
So does it works? does the function will see the class inside it module?
And more generally Could I import some function of my package inside my namespace. I though it was done this way and answer I got from internet doesn't really help me.
Yes, the function blast.foo() would know and find the class Blast.
Whenever you import a module, in part or in its entirety, the entire module is loaded - the way you import it merely decides on what classes and functions are available in the current scope, and in what way.
For example, if you call this:
from package.blast import foo
only the function foo() would be available, but the entire package read and loaded. if you were to try instantiate the class Blast by itself in the same script, this would not work.
By the way, you can make importing functions more convenient, if you customize __init__.py. In your case, if you were to edit it like so:
>>>__init__.py
from blast.py import Blast, foo
you can import both function and class like so:
from package import Blast, foo
The reason why you __all__ parameter does not work, is because it requires another import statement - mainly this:
from package import *
Calling this with your current __init__.py should work as expected.
Perhaps this post by Mike Grouchy is able to clarify things a bit more.

Python 3, imp.reload does not appear to have any effect

I am modifying a module which contains a class in it.
When I %run another module that uses the mofified class from IPython, the changes do not seem to take effect unless I restart IPython.
I have tried to use imp.reload, but this does not help. For example, I have put the following the code at the top of my module, but it does not appear to be using the updated version of my modified class (BigMySQLDatabaseGetter in the big_mysql_database_getter module)
import imp
import sys
from big_mysql_database_getter import BigMySQLDatabaseGetter
module_big_mysql_database_getter = sys.modules['big_mysql_database_getter']
imp.reload(module_big_mysql_database_getter)
Reloading a module doesn't automatically update all references that were created before, it just redefines everything within the module.
So if you do something like:
from spam import eggs
imp.reload(spam)
print(spam.eggs is eggs)
you'll get False, as eggs still references the old class. Likewise, instances created before the reload are instances of the old class, not of the new class:
import spam
e = spam.eggs()
imp.reload(spam)
print(isinstance(e, spam.eggs)) # False!
In your case, you can either reimport BigMySQLDatabaseGetter after reloading the module, or instead of directly importing the class just import the module and use big_mysql_database_getter.BigMySQLDatabaseGetter instead.

Resources