Import modules with class - python

Problem: I have got a script with a class and some functions in a folder (with __ init __ .py). In root folder I have got a main.py script.
In main script I called the module with the model:
import folder.script
And, I called module with the model:
folder.script.class.function()
'class' is the class of script used as a module. 'function' is the function relative to class.
But, I receive an output error:
TypeError: unbound method function() must be called with class instance as first argument
(got nothing instead)
Where is the mistake?

It means that function requires that there first be an instance of class before you can use it. Make your code like this:
folder.script.class(...).function()
By adding (...) after the class name, you create an instance of that class.
However, it might be better to do:
var = folder.script.class(...)
var.function()
That way, you can use the class instance later in the script under the name of var.
Or, if function is constructed in such a way that it doesn't actually need a class instance to work, why not move it out of the class altogether and place it right in the module? You should only place functions in classes if they need to be there in order to work properly.
Note: ... means to put what is needed. I don't know what arguments (if any) class.__init__ takes. If it takes none, doing just () will work.

Related

Trouble calling methods in Class

I'm having trouble calling methods in a class written by someone else (https://github.com/travishathaway/python-ach/blob/master/ach/parser.py). I have done some research but don't fully understand how to call methods with self and other arguments within a class.
The class is written out in the link above, but how do I call any of the methods written out? I have a file in the correct format asked but I cannot get the methods to work. For example, I have tried (and other variations):
a = Parser(file) # where "file" is the filepath
a.__parse_file_header()
This gives me the error: 'Parser' object has no attribute '__parse_file_header'
The methods with 2 underscores in the front are "private" to the class object itself, which is not supposed to be called externally. (Saying that you can still call private methods if you really want to, via mangling)
By the look of the Parser, you should only call as_json or as_dict of the Parser object you initiated with the string variable
eg.
parser = Parser(string_variable)
dict = parser.as_dict()

__subclasses__ not showing anything

I'm implementing a function that returns an object from the appropriate subclass. If I move SubClass from base.py, no subclasses appear for __subclasses__. Are they required to be in the same file?
Perhaps the fact that I'm never importing directly subclass.py hides the subclass from python? What can I do? I have even checked the attribute __mro__ and get_subclass points to the right class.
# project/main.py
from project.src.base import get_subclass
obj = get_subclass(cls,name) # Returns an object of a subclass of cls
# project/src/subclass.py
from project.src.base import BaseClass
class SubClass(BaseClass):
pass
# project/src/base.py
def get_subclass(cls,name):
subclss = cls.__subclasses__ # This is returning an empty list
pass
class BaseClass(object):
pass
Python only runs code of modules that are imported. If you move code to a different module but never import it, Python does not know about its contents.
You have to import the files containing the subclasses you want accessible.
# project/src/__init__.py
import project.src.base # executes the ``BaseClass`` definition
import project.src.subclass # executes the ``SubClass`` definition
Note that it does not really matter where you import these - they must be imported before you need SubClass to appear in __subclasses__, though.

Why does a class get "called" when not initiated? - Python

For example, in the following code:
class test:
print "Hi"
Python would automatically print 'hi'. Sorry if this is an obvious question, but I can't find out why Python would do that unless a 'test' object was initiated.
* I just started programming in general a few months ago and Python is my first language, so please spare some mercy on me.
You are building a class; the body of a class is executed as a function to build the definition. The local namespace of that 'function' forms the set of attributes that make up the class. See the class statement documentation.
Methods in the class body are not executed; like function definitions, you need to call them first. But if you didn't first call the class body, you don't know what methods the class has, at all.
In the same way, any top-level code in a module is executed when you import a module, to form the module namespace. If you put print "Hi" in a module, it is also executed immediately.

How to access a function contained within a class in another module

This should be relatively simple, but I'm just missing something. I am trying to utilize a function from another module which is contained within a class. I can do it easily when there is no class involved.
# a.py
import b
b.name()
--
# b.py
def name():
print "What is your name?"
class details(object):
def age():
print "What is your age?"
When I run a i get the expected result of
What is your name?
However when i try to access "def age()" from another module it keeps giving me trouble.
Some of what I have tried so far...
# c.py
import b
b.details.age()
= TypeError: unbound method age() must be called with details instance as first argument (got nothing instead)
# c.py
from b import details
details.age()
= TypeError: unbound method age() must be called with details instance as first argument (got nothing instead)
# c.py
from b import details
b.details(age)
= NameError: name 'b' is not defined
I have tried a few others as well but too many to reasonably post. What am i doing wrong? What is the syntax to do do this? Is it even possible to execute a function when it is contained within a class in another module?
Thanks in advance
EDIT: Fixed all tabs to spaces as suggested by Mike Graham
The first parameter of all class methods in Python is a reference to the current object (normally this is called self). However, that said, you seem to be trying to use it as a static method and not as an instance method, so perhaps you meant to use the #staticmethod decorator:
class Details: # class names in Python should generally be CamelCased.
# please note the comments below
#staticmethod
def age():
print 'What is your age?'
Or, if you really want it to be an instance method, then you need to add self and change how you're referencing it:
class Details:
def age(self):
print 'What is your age?'
# c.py
from b import Details
#you must create an instance of the class before you can call methods on it.
d = Details()
d.age()
EDIT
As noted in the comments, it is rare that #staticmethod has a genuine use case (it is often better to organize your code with modules, for example). You will often come across #classmethod as an alternative. Please note, though, that methods decorated with #classmethod have a reference to the current class as the first parameter. This question addresses the major differences.

Function call in Google App Engine - Python

In main.py I have a display code that repeats several times. So I created a f1.py and placed the code in f1.py as a function display(query) and I am calling it from main.py as f1.display(query).
But display(query) has the line
self.response.out.write(
# some code
)
and I get the error message:
self.response.out.write(
NameError: global name 'self' is not defined
I tried to import from google.appengine.ext import webapp inside the display(query) function but that did not help.
What am I doing wrong and how can I fix it? Thanks!
self is a conventional name for the first argument passed to a class instance's methods. A class instance will pass a reference to itself as the first argument to all of it's methods when they are called. It's common practice to name the first parameter for instance methods self.
So, when you factored out part of your method's (presumably get or post on a sublcass of webapp.RequestHandler) functionality to another function, you can no longer refer to self and get the response property.
The easiest way to fix this would probably be to return the output you wish to write to the response in the function. Then you can call self.response.out.write with your function's return value from within in the method as you did before the refactor.

Categories