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.
Related
I made an app for analysing data, all in one file, but i read that it needs to be made in objective style. Trying to make it objective I get an error that module doesnt have attribute (which it has)
Tried to disable linting and organise code in a different way but end up with this error all the time
file - analyser.py
import argparse
import helper
class analyser:
def __init__(self):
pass
def cli(self):
#some code
if __name__ == '__main__':
analyser.cli
helper.analyse(arguments)
file - helper.py
import csv
class helper:
def __init__(self):
pass
def analyse(self, arguments):
#code
I get
AttributeError: module 'analyser' has no attribute 'analyse'
The module helper does not have an attribute analyse. However, the class helper does have one. You can do one of the following to access the analyse function:
from helper import helper
...
helper.analyse(arguments)
Or
import helper
...
helper.helper.analyse(arguments)
At the moment, the 2 classes helper and analyser are redundant. You may be better off just using functions. Object-oriented programming is useful in certain circumstances to encapsulate data and for abstraction, but functional programming has its own uses and it is good to know when to use either.
TL; DR
Basically the question is about hiding from the user the fact that my modules have class implementations so that the user can use the module as if it has direct function definitions like my_module.func()
Details
Suppose I have a module my_module and a class MyThing that lives in it. For example:
# my_module.py
class MyThing(object):
def say():
print("Hello!")
In another module, I might do something like this:
# another_module.py
from my_module import MyThing
thing = MyThing()
thing.say()
But suppose that I don't want to do all that. What I really want is for my_module to create an instance of MyThing automatically on import such that I can just do something like the following:
# yet_another_module.py
import my_module
my_module.say()
In other words, whatever method I call on the module, I want it to be forwarded directly to a default instance of the class contained in it. So, to the user of the module, it might seem that there is no class in it, just direct function definitions in the module itself (where the functions are actually methods of a class contained therein). Does that make sense? Is there a short way of doing this?
I know I could do the following in my_module:
class MyThing(object):
def say():
print("Hello!")
default_thing = MyThing()
def say():
default_thing.say()
But then suppose MyThing has many "public" methods that I want to use, then I'd have to explicitly define a "forwarding" function for every method, which I don't want to do.
As an extension to my question above, is there a way to achieve what I want above, but also be able to use code like from my_module import * and be able to use methods of MyThing directly in another module, like say()?
In module my_module do the following:
class MyThing(object):
...
_inst = MyThing()
say = _inst.say
move = _inst.move
This is exactly the pattern used by the random module.
Doing this automatically is somewhat contrived. First, one needs to find out which of the instance/class attributes are the methods to export... perhaps export only names which do not start with _, something like
import inspect
for name, member in inspect.getmembers(Foo(), inspect.ismethod):
if not name.startswith('_'):
globals()[name] = member
However in this case I'd say that explicit is better than implicit.
You could just replace:
def say():
return default_thing.say()
with:
say = default_thing.say
You still have to list everything that's forwarded, but the boilerplate is fairly concise.
If you want to replace that boilerplate with something more automatic, note that (details depending on Python version), MyThing.__dict__.keys() is something along the lines of ['__dict__', '__weakref__', '__module__', 'say', '__doc__']. So in principle you could iterate over that, skip the __ Python internals, and call setattr on the current module (which is available as sys.modules[__name__]). You might later regret not listing this stuff explicitly in the code, but you could certainly do it.
Alternatively you could get rid of the class entirely as use the module as the unit of encapsulation. Wherever there is data on the object, replace it with global variables. "But", you might say, "I've been warned against using global variables because supposedly they cause problems". The bad news is that you've already created a global variable, default_thing, so the ship has sailed on that one. The even worse news is that if there is any data on the object, then the whole concept of what you want to do: module-level functions that mutate a shared global state, carries with it most of the problems of globals.
Not Sure why this wouldn't work.
say = MyClass().say()
from my_module import *
say
>>Hello!
I have a module which can be described as
python
class Symbol():
def __init__(data):
self.data = data
pass
def __add__(self,other):
return Add(self,other)
class Integer(Symbol):
pass
class Add(Symbol):
def __init__(a,b):
self.data = [a,b]
I want to split it into three files, which are symbol.py, integer.py and add.py; there are of course going to be a lot more details on those classes so having them in one files is ridiculous.
For some reason the imports never seem to work, while it's not even complaining of circular dependencies, can someone give me a little example?
Your circular dependency situation isn't unsolvable, because Symbol doesn't depend on Add at definition time, only when the __add__ method is called. There are two good ways to resolve it.
The first is to not have the module Symbol is in import Add at top level, but only do that within the __add__ method itself. For instance, if your modules were named after the classes (only lowercase), you'd use this in symbol.py:
class Symbol():
# ...
def __add__(self,other):
from add import Add
return Add(self,other)
The other approach is to import Add globally into the symbol module, but do so after the definintion of the Symbol class. This way, when the add module imports symbol back, it will always be able to see the Symbol class's definition, even if the rest of the module is not finished loading.
class Symbol():
# same as in your current code
from add import Add
If you go with this second approach and the Symbol class imports other stuff at the top of the file (where import statements normally are put), you might want to add a comment in that space about Add being imported later (and why).
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.
I have a specific question regarding the usage of profiler. I am new to python programming
I am trying to profile a function which I want to invoke as a class method, something like this
import profile
class Class:
def doSomething():
do here ..
def callMethod():
self.doSomething()
instead of this I want to use
profile.run(self.doSomething())
but the profile.run expects the string inside it and I get error
TypeError: exec: arg 1 must be a string, file, or code object
Can somebody please help?
Thank you
Fixed!!!
Instead of profile, I used cProfile module that as per the python docs has much lesser overhead
Ref : http://docs.python.org/library/profile.html#introduction-to-the-profilers
with cProfiler, one can actually pass the local and global params using the runctx module
so for the same problem, I did the following:
import cProfile
cProfile.runctx('self.doSomething()',globals(),locals())
and it worked :)
also, if you have more params to pass you can like
import cProfile
cProfile.runctx('self.doSomething(x,y,z)',globals(),locals())
Thanks for all help
You need to fix various imprecisions (missing self, saying you're using class methods when there's no classmethod in sight, failing to inherit from object, ...) then make profile happy by giving it a string as it wants -- and the name of the instance must be made globally visible so that profile can actually use that string. For example:
import profile
import time
class Class(object):
def doSomething(self):
time.sleep(0.1)
def callMethod(self):
global _o
_o = self
profile.run('_o.doSomething()')
o = Class()
o.callMethod()