import & structure python modules / classes - python

im working on some basic python stuff within the google app engine and I was unable to figure out the correct way to structure my handlers.
/main.py
/project/handlers/__init__.py
/project/handlers/AccountHandler.py
the AccountHandler is basically a class
class AccountHandler(webapp.RequestHandler):
when im using from project.handlers import AccountHandler
python always give me a
TypeError: 'module' object is not callable
how do i have to name/import/structure my classes?
cheers,
Martin

To quote from the docs:
A module is a file containing Python definitions and statements. The file name is the module name with the suffix .py appended.
The AccountHandler you are importing is the module /project/handlers/AccountHandler.py in this case. The file AccountHandler.py is not callable, and the interpreter tells you this. To call the class you defined in your file just use:
from project.handlers.AccountHandler import AccountHandler
# Alternately
# from project.handler import AccountHandler
# AccountHandler.AccountHandler() # will also work.

You need to rename init.py to __init__.py

Related

Import by filenames passed as arguments

I am developing a Python package which does work by taking in user-defined objects all of which are instances of a class which I wrote. The way I have designed is, user passes his/her objects as defined in one or more python scripts (see example below).
I want to access the objects which user defines in the scripts. How can I do that?
I looked at import by filename but to no avail. I even went on to use imp.load_source but didn't solve.
Some typical user-defined objects
Assume for the sake of the problem, all methods are defined in Base. I understand what I am asking for leads to arbitrary code execution, so I am open to suggestions wherein users can pass their instances of the Base class arbitrarily but safely.
foo.py has the following code:
from package import Base
foo = Base('foo')
foo.AddBar('bar', 'bar')
foo.AddCow('moo')
ooo.py :
from package import Base
ooo = Base('ooo')
ooo.AddBar('ooo','ooo')
ooo.AddO(12)
And I run my main program as,
main_program -p foo.py ooo.py
I want to be able to access foo, ooo in the main_program body.
Tried:
I am using python2.7 I know I am using older Python, I will make the move soon
importlib
Tried importlib.import_module but it throws ImportError: Import by filename is not supported.
__import__
I tried using __import__('/path/to/file.py') but it throws the same ImportError: Import by filename is not supported.
At this point, any solution which lets me use objects defined in user-input scripts works.
If you are okay with skipping the .py in the filename, this can be solved by asking the user to pass the module name (basically the file name without the py) extension
Referring to this answer and this book, here is an example
tester.py
class A:
def write(self):
print("hello")
obj = A()
Now we want to dynamically access obj from a file called test.py, so we do
python test.py tester
And what does test.py do? It imports the module based on name and access it methods. Note that this assumes you are not concerned about the order in which the user passes the objects
test.py
import sys
# Get all parameters (sys.argv[0] is the file name so skipping that)
module_names = sys.argv[1:]
# I believe you can also do this using importlib
modules = list(map(__import__, module_names))
# modules[0] is now "tester"
modules[0].obj.write()
Mapping this to your example, I think this should be
foo.py
from package import Base
foo = Base('foo')
foo.AddBar('bar', 'bar')
foo.AddCow('moo')
ooo.py
from package import Base
ooo = Base('ooo')
ooo.AddBar('ooo','ooo')
ooo.AddO(12)
And run main program as
python main_program.py foo ooo
Have you tried
from (whatever the file name is) import *
Also don’t include .py in the file name.

Python module' object is not callable

This is a python rooky question...
The file structure is like that
./part/__init__.py
./part/Part.py
./__init__.py
./testCreation.py
when running python3 testCreation.py I get a
part = Part() TypeError: 'module' object is not callable
no complain about import. so I wonder what the issue is !?
also coming from Java, can some one comment if organising classes for python is better just in packages with subpaths or in modules (ommit the init.py file) ?
In Python, you need to distinguish between module names and class names. In your case, you have a module named Part and (presumable) a class named Part within that module. You can now use this class in another module by importing it in two possible ways:
Importing the entire module:
import Part
part = Part.Part() # <- The first Part is the module "Part", the second the class
Import just the class from that module into your local (module) scope:
from Part import Part
part = Part() # <- Here, "Part" refers to the class "Part"
Note that by convention, in Python modules are usually named in lowercase (for instance part), and only classes are named in UpperCamelCase. This is also defined in PEP8, the standardized coding style guide for Python.

Packages, Modules, and classes within those

What is the "correct" way to import/use classmethods when my class is part of a module?
I created a Python utility for my co-workers, basically using my Java knowledge, Stack Overflow and Google. It works fine, but an experienced Python person reviewed everything and suggested to improve the pythonicity of the code.
Initially, I just used sys.path.append() to add sub-directories that would contain many .py files (basically one class within each .py).
Now I am trying to get the thing working with packages and modules:
I added (empty) __init__.py files in my root directory, and all sub-directories;
I turned all my classes into "modules", by adding __name__ = "whatever-filename" at line 1.
And, well, imports work. In my main script, I can do
from classes import MyHelper
(where classes refers to a sub-directory, and MyHelper to a module within). But:
MyHelper.some_class_method()
gives me:
Traceback (most recent call last):
File "./xyz", line 12, in <module>
MyHelper.some_class_method()
AttributeError: 'module' object has no attribute 'some_class_method'
But I didn't change MyHelper - it still has all the #classmethods that I could use before introducing packages/modules.
Edit: MyHelper looks like this:
__name__ = "MyHelper"
...
class MyHelper(object):
"""This class..."""
...
MyHelper refers to a module name when imported, not the class name which is the same. You can try the following import instead to import a class from a module in a child directory.
from classes.MyHelper import MyHelper
MyHelper.calling_my_class_method_here()
from X import Y
is really importing a class or function Y from the module X into the current module's namespace, and you can use Y directly.
Alternatively, if you just imported the module X, eg
import X
then you would call the function (or class) Y as X.Y. So in your case, try just
import MyHelper
MyHelper.some_class_method()

How to extend or monkey-patch a built-in module

I want to write a custom json module for my team,
First I created a 'json.py' file under the folder(namespace) 'dqa_fileio/config'
so when others want to use my module, it should be called by import dqa_fileio.config.json
Then, I want to creates a read_file method to load a json file
But I got AttributeError: 'module' object has no attribute 'load'
I think that because the file_name is called json.py,
But I want to keep the filename, is there anyway like Ruby that I can open a class to extend it's ability ? But it seems the json is a folder(namespace) not a class ? Please correct me if any wrong concept. Thanks
json.py (under the namespace dqa_fileio/config)
import json
class Json(object):
def __init__(self):
pass
def read_file(self, file_name):
return json.load(open(file_name, 'r'))
if __name__ == '__main__':
Json().read_file(sys.argv[1])
That won't work because how do you think python is supposed to know which one to choose?
You have to pick a different name, as long as you want import json to import the correct module.
Look here for more information on the same type of question.
The only other thing I would suggest is to use a package.
Put your json.py module in some kind of package.
e.g:
common
|-__init__.py
|-json.py
Put common in your PYTHONPATH and/or package it up nicely with an appropriate setup.py which your team can install and use in their projects.
Then import it like:
from common import json
See: https://docs.python.org/2/tutorial/modules.html
The problem is that python thinks import json is just importing itself, and your class has no load method. The only way to get around this is to change your file name, or use some very unpythonic circular imports.

I'm getting AttributeError when I call a method in other class

I'm very new to Python and I have a code like this:
class Configuration:
#staticmethod
def test():
return "Hello World"
When I call the method test from other python code like this:
import test
test.Configuration.test()
I get an error like this:
Traceback (most recent call last):
File "example.py", line 3, in <module>
test.Configuration.test()
AttributeError: 'module' object has no attribute 'test'
where I'm making the mistake?
Edit:
My directory structure:
root
--example.py
--test
----__init.py__
----Configuration.py
Python module names and the classes they contain are separate. You need use the full path:
import test
print test.Configuration.Configuration.test()
Your test package has a module named Configuration, and inside that module is your Configuration class.
Note that Python, unlike Java, lets you define methods outside classes too, no need to make this a static method. Nor do you need to use a separate file per class.
Try to rename your module to something other than 'test', since this is the name of a standard library module (http://docs.python.org/2/library/test.html) and probably you're importing that module instead of your own. Another option is to add the directory containing your test module into the PYTHONPATH environment variable, so that python may find it instead of the standard library module (but this is not advised as it shadows the standard module and you won't be able to import it later).
To check which file you're importing from, do:
import test
print test

Categories