I have a module named jaguar which has different classes under it. Each class has many functions inside it. When I import the whole module by
import jaguar as jg
and then try to call a function named read_excel, it is showing error as
AttributeError: module 'jaguar' has no attribute named 'read_excel'
Instead if I call each class by class and use it, it will work.
Could someone please help me to sort out the issue?
Without seeing your code, it's difficult to be 100% certain what is happening. In the future, it is likely that you'll get more and better answers to your questions if you include a Minimal, Complete, and Verifiable example.
It seems best to avoid details of how Python finds functions and methods when they are called (doubly so, since I'm no expert in this subject.) That said, it seems the issue is that you are trying to call a function as if it was defined at the module level. However, the function in question is actually a method defined within a class (inside that module). It seems you have a jaguar.py file structured something like:
""" jaguar module does jaguar-y stuff """
class TheClass:
def __init__(self):
# Do object initialization stuff
def read_excel(self):
print('In read_excel()')
And in your program file you're trying to do something like this:
""" main program """
import jaguar as jg
jg.read_excel()
Which will result in an AttributeError because the function is not found at the module level. Instead, you need to instantiate an object and then call the method:
""" main program """
import jaguar as jg
my_ob = jg.TheClass()
my_ob.read_excel()
Alternatively, you might be able to define the function at the module level - i.e. outside of classes - if that works for what you are trying to do. So jaguar.py would be structured something like:
""" jaguar module does jaguar-y stuff """
def read_excel():
print('In read_excel()')
class TheClass:
def __init__(self):
# Do object initialization stuff
This latter example will allow you to call read_excel() via jg.read_excel(), as in the first main program example above.
You might find it helpful to go through the tutorial on Python Modules.
I'm doing a Data Science project in Python in which many functions and objects have been refactored into classes. One of these classes is the Universe() which contains all names and attributes in our database. As you can imagine, it's huge (takes well over 5 minutes to load) and it's imported in at least two other classes (thus slowing the other class instantiations down considerably).
I'd like to make it so that in the running kernel this class is only instantiated once even when imported from other classes (thus minimizing Database interaction). I've thought of using static classes but from what I've read python developers absolutely hate static classes and consider it non-pythonic.
Are there any other more pythonic solutions to this problem? How would you define a class that encapsulates data and minimizes Database interaction for all other classes that use it?
You can create and instantiate a class in its own module, at module level. That module will only be imported once, and thus the class is only instantiated once.
Example:
file: uni.py:
class _Universe:
def __init__(self):
print('init')
self.get_database_info()
def get_database_info(self):
print('db info')
Universe = _Universe()
file: unia.py:
import unib
from uni import Universe
file: unib.py:
from uni import Universe
Executing file unia.py suggest the Universe class is imported twice, but looking at the output (from the print functions), you'll see instantiating this happens once: Python is smart enough to re-use the already imported module:
python unia.py:
output:
init
db info
Note that I'm using _Universe, so the class instance can be called Universe, to ease code changes
If you have code where Universe() is instantiated (outside the uni module), you could cheat somewhat and add the __call__() method to _Universe. Though it'd be better and clearer to rewrite those little bits of code from e.g. universe = Universe() to Universe:
class _Universe:
def __init__(self):
print('init')
self.get_database_info()
def get_database_info(self):
print('db info')
def __call__(self):
return self
and now in e.g. unia.py, you could have:
import unib
from uni import Universe
universe = Universe()
without repercussions.
Since that, however, may lead to confusion (why "instantiate" an instance?), it's better not to. Perhaps just for an initial quick test and timing of results.
I have used python unittest quite a bit and there is a decorator method you can use to conditionally skip tests like this:
import unittest
class TestStringMethods(unittest.TestCase):
#unittest.skipIf(1 == 1, 'Skipped because 1 does indeed equal 1')
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
I wanted to add some features to the unittest.TestCase class though, so I subclassed it to start adding my own custom code:
import unittest
class CustomTestCase(unittest.TestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # Just use whatever is in TestCase's init + our stuff
self.foo = 'foo' # our stuff
self.bar = 'bar'
def mymethod(self, param1, param2): # Some custom method I wanted to make for these custom test cases
pass
To continue using #unittest.skipIf I have been sticking import unittest at the top of any of my CustomTestCase test files, but I wonder if thats the correct way to be doing things. Am I importing more than I need? Or am I worried about nothing?
The fact that you've subclassed has little to do with what you're asking. In general, it's fine for subclasses to import or use their superclass: in fact, they must import their superclass when they're defined. It's the other way around that's the problem (superclass shouldn't know about its subclasses).
To continue using #unittest.skipIf I have been sticking import
unittest at the top of any of my CustomTestCase test files, but I
wonder if thats the correct way to be doing things. Am I importing
more than I need?
If you want to use any attribute off of the unittest module (including the skipIf decorator), then you have to import it into the module in question. It's no more complex than that.
If you're worried about something like header guards, like you need for C/C++ development, don't be. It doesn't work like the #include preprocessor directive (i.e. it's not actually including the source of the unittest module in your file).
If you're worried about importing unittest too many times, don't be. It's extremely common to import a module like unittest into many different modules of a given project.
Or am I worried about nothing?
Yes. Just import unittest whenever you need it and rid yourself of worry!
HTH.
I'm developing a PyQT4 application, and it's getting pretty hard for me to navigate through all of the code at once. I know of the import foo statement, but I can't figure out how to make it import a chunk of code directly into my script, like the BASH source foo statement.
I'm trying to do this:
# File 'functions.py'
class foo(asd.fgh):
def __init__(self):
print 'foo'
Here is the second file.
# File 'main.py'
import functions
class foo(asd.fgh):
def qwerty(self):
print 'qwerty'
I want to include code or merge class decelerations from two separate files. In PHP, there is import_once('foo.php'), and as I mentioned previously, BASH has source 'foo.sh', but can I accomplish this with Python?
Thanks!
For some reason, my first thought was multiple inheritance. But why not try normal inheritance?
class foo(functions.foo):
# All of the methods that you want to add go here.
Is there some reason that this wont work?
Since you just want to merge class definitions, why don't you do:
# main.py
import functions
# All of the old stuff that was in main.foo is now in this class
class fooBase(asd.fgh):
def qwerty(self):
print 'qwerty'
# Now create a class that has methods and attributes of both classes
class foo(FooBase, functions.foo): # Methods from FooBase take precedence
pass
or
class foo(functions.foo, FooBase): # Methods from functions.foo take precedence
pass
This takes advantage of pythons capability for multiple inheritance to create a new class with methods from both sources.
You want execfile(). Although you really don't, since redefining a class, uh... redefines it.
monkey patching in python doesn't work in nearly the same way. This is normally considered poor form, but if you want to do it anyways, you can do this:
# File 'functions.py'
class foo(asd.fgh):
def __init__(self):
print 'foo'
the imported module remains unchanged. In the importing module, we do things quite differently.
# File 'main.py'
import functions
def qwerty(self):
print 'qwerty'
functions.foo.qwerty = qwerty
Note that there is no additional class definition, just a bare function. we then add the function as an attribute of the class.
What are the best practices for extending an existing Python module – in this case, I want to extend the python-twitter package by adding new methods to the base API class.
I've looked at tweepy, and I like that as well; I just find python-twitter easier to understand and extend with the functionality I want.
I have the methods written already – I'm trying to figure out the most Pythonic and least disruptive way to add them into the python-twitter package module, without changing this modules’ core.
A few ways.
The easy way:
Don't extend the module, extend the classes.
exttwitter.py
import twitter
class Api(twitter.Api):
pass
# override/add any functions here.
Downside : Every class in twitter must be in exttwitter.py, even if it's just a stub (as above)
A harder (possibly un-pythonic) way:
Import * from python-twitter into a module that you then extend.
For instance :
basemodule.py
class Ball():
def __init__(self,a):
self.a=a
def __repr__(self):
return "Ball(%s)" % self.a
def makeBall(a):
return Ball(a)
def override():
print "OVERRIDE ONE"
def dontoverride():
print "THIS WILL BE PRESERVED"
extmodule.py
from basemodule import *
import basemodule
def makeBalls(a,b):
foo = makeBall(a)
bar = makeBall(b)
print foo,bar
def override():
print "OVERRIDE TWO"
def dontoverride():
basemodule.dontoverride()
print "THIS WAS PRESERVED"
runscript.py
import extmodule
#code is in extended module
print extmodule.makeBalls(1,2)
#returns Ball(1) Ball(2)
#code is in base module
print extmodule.makeBall(1)
#returns Ball(1)
#function from extended module overwrites base module
extmodule.override()
#returns OVERRIDE TWO
#function from extended module calls base module first
extmodule.dontoverride()
#returns THIS WILL BE PRESERVED\nTHIS WAS PRESERVED
I'm not sure if the double import in extmodule.py is pythonic - you could remove it, but then you don't handle the usecase of wanting to extend a function that was in the namespace of basemodule.
As far as extended classes, just create a new API(basemodule.API) class to extend the Twitter API module.
Don't add them to the module. Subclass the classes you want to extend and use your subclasses in your own module, not changing the original stuff at all.
Here’s how you can directly manipulate the module list at runtime – spoiler alert: you get the module type from types module:
from __future__ import print_function
import sys
import types
import typing as tx
def modulize(namespace: tx.Dict[str, tx.Any],
modulename: str,
moduledocs: tx.Optional[str] = None) -> types.ModuleType:
""" Convert a dictionary mapping into a legit Python module """
# Create a new module with a trivially namespaced name:
namespacedname: str = f'__dynamic_modules__.{modulename}'
module = types.ModuleType(namespacedname, moduledocs)
module.__dict__.update(namespace)
# Inspect the new module:
name: str = module.__name__
doc: tx.Optional[str] = module.__doc__
contents: str = ", ".join(sorted(module.__dict__.keys()))
print(f"Module name: {name}")
print(f"Module contents: {contents}")
if doc:
print(f"Module docstring: {doc}")
# Add to sys.modules, as per import machinery:
sys.modules.update({ modulename : module })
# Return the new module instance:
return module
… you could then use such a function like so:
ns = {
'func' : lambda: print("Yo Dogg"), # these can also be normal non-lambda funcs
'otherfunc' : lambda string=None: print(string or 'no dogg.'),
'__all__' : ('func', 'otherfunc'),
'__dir__' : lambda: ['func', 'otherfunc'] # usually this’d reference __all__
}
modulize(ns, 'wat', "WHAT THE HELL PEOPLE")
import wat
# Call module functions:
wat.func()
wat.otherfunc("Oh, Dogg!")
# Inspect module:
contents = ", ".join(sorted(wat.__dict__.keys()))
print(f"Imported module name: {wat.__name__}")
print(f"Imported module contents: {contents}")
print(f"Imported module docstring: {wat.__doc__}")
… You could also create your own module subclass, by specifying types.ModuleType as the ancestor of your newly declared class, of course; I have never personally found this necessary to do.
(Also, you don’t have to get the module type from the types module – you can always just do something like ModuleType = type(os) after importing os – I specifically pointed out this one source of the type because it is non-obvious; unlike many of its other builtin types, Python doesn’t offer up access to the module type in the global namespace.)
The real action is in the sys.modules dict, where (if you are appropriately intrepid) you can replace existing modules as well as adding your new ones.
Say you have an older module called mod that you use like this:
import mod
obj = mod.Object()
obj.method()
mod.function()
# and so on...
And you want to extend it, without replacing it for your users. Easily done. You can give your new module a different name, newmod.py or place it by same name at a deeper path and keep the same name, e.g. /path/to/mod.py. Then your users can import it in either of these ways:
import newmod as mod # e.g. import unittest2 as unittest idiom from Python 2.6
or
from path.to import mod # useful in a large code-base
In your module, you'll want to make all the old names available:
from mod import *
or explicitly name every name you import:
from mod import Object, function, name2, name3, name4, name5, name6, name7, name8, name9, name10, name11, name12, name13, name14, name15, name16, name17, name18, name19, name20, name21, name22, name23, name24, name25, name26, name27, name28, name29, name30, name31, name32, name33, name34, name35, name36, name37, name38, name39
I think the import * will be more maintainable for this use-case - if the base module expands functionality, you'll seamlessly keep up (though you might shade new objects with the same name).
If the mod you are extending has a decent __all__, it will restrict the names imported.
You should also declare an __all__ and extend it with the extended module's __all__.
import mod
__all__ = ['NewObject', 'newfunction']
__all__ += mod.__all__
# if it doesn't have an __all__, maybe it's not good enough to extend
# but it could be relying on the convention of import * not importing
# names prefixed with underscores, (_like _this)
Then extend the objects and functionality as you normally would.
class NewObject(object):
def newmethod(self):
"""this method extends Object"""
def newfunction():
"""this function builds on mod's functionality"""
If the new objects provide functionality you intend to replace (or perhaps you are backporting the new functionality into an older code base) you can overwrite the names
May I suggest not to reinvent the Wheel here? I'm building a >6k line Twitter Client for 2 month now, at first I checked python-twitter too, but it's lagging a lot behind the recent API changes,, Development doesn't seem to be that active either, also there was(at least when I last checked) no support for OAuth/xAuth).
So after searching around a bit more I discovered tweepy:
http://github.com/joshthecoder/tweepy
Pros: Active development, OAauth/xAuth and up to date with the API.
Chances are high that what you need is already in there.
So I suggest going with that, it's working for me, the only thing I had to add was xAuth(that got merge back to tweepy :)
Oh an a shameless plug, if you need to parse Tweets and/or format them to HTML use my python version of the twitter-text-* libraries:
http://github.com/BonsaiDen/twitter-text-python
This thing is unittestetd an guaranteed to parse Tweets just like Twitter.com does it.
Define a new class, and instead of inherit it from the class you want to extend from the original module, add an instance of the original class as an attribute to your new class.
And here comes the trick: intercept all non-existing method calls on your new class and try to call it on the instance of the old class.
In your NewClass just define new or overridden methods as you like:
import originalmodule
class NewClass:
def __init__(self, *args, **kwargs):
self.old_class_instance = originalmodule.create_oldclass_instance(*args, **kwargs)
def __getattr__(self, methodname):
"""This is a wrapper for the original OldClass class.
If the called method is not part of this NewClass class,
the call will be intercepted and replaced by the method
in the original OldClass instance.
"""
def wrapper(*args, **kwargs):
return getattr(self.old_class_instance, methodname)(*args, **kwargs)
return wrapper
def new_method(self, arg1):
"""Does stuff with the OldClass instance"""
thing = self.old_class_instance.get_somelist(arg1)
# returns the first element only
return thing[0]
def overridden_method(self):
"""Overrides an existing method, if OldClass has a method with the same name"""
print("This message is coming from the NewClass and not from the OldClass")
In my case I used this solution when simple inheritance from the old class was not possible, because an instance had to be created not by its constructor, but with an init script from an other class/module. (It is the originalmodule.create_oldclass_instance in the example above.)