calling a method inside a class from a different file - python

I am trying to implement python classes and objects in my application code. Currently, I have a file that includes all the frequently used functions. I import them in another file.
funcs.py
class name1():
def func1(x):
return x
def func2(y):
return y
....
file1.py
from funcs import func1
from funcs import func2
I'd like to organize the code in class, method and attributes and then invoke them in different files.
How do I call a method within a class from another file? What changes do I need to make in funcs.py file?

If you want to call a method within a class, first you have to instantiate an object of that class, and then call the method in reference to the object. Below is not an ideal implementation but it's just for example.
example.py
class MyClass:
def my_method(self):
print('something')
object1 = MyClass()
object1.my_method()
Then when you want to call the method in another file you have to first import them.
another.py
from .example import MyClass
object2 = MyClass()
object2.my_method()
If you just want to call the method without having to create an object first you can use #staticmethod.
class MyClass:
#staticmethod
def my_method(self):
print('something')
MyClass.my_method()
Yet as I said this is not the ideal implementation. As #juanpa.arrivillaga said ideally you cannot just throw in any method and bundle them into a single class. The content of a class is all related to the object you want to define as a class.

Related

patching instantiated object method call in python

Suppose we have
import XYZ
Class(object):
def __init__(self):
pass
def some_call(self)
#other logic
obj = XYZ()
obj.do_something()
In my unittest I'm trying to patch XYZ, and the call to do_something. I want to call some_call in my unittest because I have other logic to perform, but specifically the one instance and method call on the instance I want to bypass.

python call methods from super class

I am trying to understand python inheritance a little. Here is a use case:
class Test:
def hello():
print("hello")
return "hello"
def hi():
print(hello())
print("HI")
class Test1(Test):
hi()
pass
x = Test1()
x.hello()
I don't understand why I can't call "hi()" in class Test1. It inherited it class Test right?
I think you are misunderstanding the relationship and definitions of classes and objects. Classes are like blueprints to create objects. By writing methods inside a class, you are essentially defining the behaviors of the object that can be created from the class blueprint. So, with your code:
class Test:
def hello():
print("Hello")
return "Hello"
def hi():
print(hello())
print("Hi")
class Test1(Test):
hi() # <- You really shouldn't call a method directly from a "blueprint" class
pass
x = Test1()
x.hello()
While your last two lines of code are valid, it's a bad idea (and almost always invalid) to call a method outside of the class's scope directly inside a class definition. The reason why hi() does not work in the Test1 class is that it's not defined in the scope of Test1; even though this class indeed inherits from the Test class, it only affects the object that is created from the class (like the object x you created from the Test1() class).
Here's a more detailed explanation about classes and objects from another relevant question: What are classes, references and objects?
Hope this helped!

How to use self parameter, #staticmethod keyword inside a class and its methods

I have a python class which has multiple methods. I have defined my methods via #staticmethod instance and I want to call other methods of my class from inside my main function(main_function). I think I need self parameter for calling my other functions from my main function and I want to pass this parameter to my main_function when I create an instance of my class.
class myclass:
#staticmethod
def function1(param1)
print "function1"
#staticmethod
def main_function(self, param1)
function1(param1)
my_object = myclass()
my_object.main_function(param1)
I got this error:
TypeError: main_function() takes exactly 2 arguments (1 given)
The problem is that I have not self parameter when I create my instance. I tried to remove #staticmethod keyword from my method definition and remove all self parameter using, but this does not work.
Only use #staticmethod if you are creating a function that you'd normally want to tie to specific classes but do not need any other context. For example, the str.maketrans() function is a static method because it is a utility function you'd often use when working with strings, namespacing it to the already-existing str type (which pre-exists as a class) makes sense there.
You appear to be using classes as a namespace instead. Don't do that. Use a module for your functions, and you don't have to worry about the special scoping rules that apply to classes. Only use a class when you need to bundle state with functionality.
If you insist on using classes with static methods anyway, you are stuck with hardcoding the class name everywhere:
class myclass:
#staticmethod
def function1(param1)
print "function1"
#staticmethod
def main_function(param1)
# Want to use other functions in this class? Then you will
# have to use the full name of the class as a prefix:
myclass.function1(param1)
You could make use of classmethods instead so you have a reference to the class object:
class myclass:
#staticmethod
def function1(param1)
print "function1"
#classmethod
def main_function(cls, param1)
# Now you can use the `cls` reference to access other attributes
cls.function1(param1)
This has the added advantage that you can use inheritance.
However, using a module is the correct way to organise a set of functions into a namespace. Put everything into a my_module.py file in your package, and use importing;
import my_module
my_module.main_function(param1)
Now all globals in my_module are bundled into one module object, and no prefixing or cls references are needed.

Execute Method within Class Python

I'm trying to call a method within a class MyClass and have its value returned.
class MyClass:
def __init__(self):
print " Class Initialized"
def gather_path(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
return self.tld_object
How do I return the value of self.tld_object by importing my class in Python intrepreter.
I'm importing like:
from MyApp.MyClass import gather_path()
I know, this is quite basic - I'm relatively new to OOP in Python.
how do I then call this method to return the value of return self.tld_object within gather_path() method?
It depends on what you're trying to do, but typically, I think the code importing your class would look like this:
from MyApp import MyClass
my_instance = MyClass()
value = my_instance.gather_path()
The value variable will now contain tld_object's value.
If you don't want to instantiate MyClass in order to call get_path(), you need to make get_path() either a class or static method.
From your example, it's not clear that you need to set self.tld_object, since you're just returning it from gather_path() anyway, unless other methods are relying on that state under the hood. If you are, though, it would be better practice to declare it in __init__, even if you set it to None. Alternatively, if all instances of MyClass are going to use the same value of tld_object, you could make it a class variable, and just declare it outside of any method, like so:
class MyClass:
tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
def gather_path(self):
return self.tld_object
Not sure how much of that is relevant to your needs, it's a bit hard to tell from the given example. If I were writing this (given what you've said so far), I'd do the following:
class MyClass:
def __init__(self):
self.tld_object = Tld.objects.get(id=3,FKToClient=User.pk)
# Maybe raise an exception or something if self.tld_object doesn't get set right
# Example of how to access tld_object from another method
def print_tld_object(self):
print self.tld_object
If you need to reach tld_object from outside the class, you would do the following in the other module:
from MyApp import MyClass
my_instance = MyClass()
tld = my_instance.tld_object

calling class/static method from class variable in python

I'm trying to make a ImageLoader class handle the loading and processing of image resources like this:
class ImageLoader:
TileTable = __loadTileTable('image path', some other variable)
#staticmethod
def _loadTileTable(arg1, arg2):
blah blah
however, on compile i get: NameError: name '_loadTileTable' is not defined
If i replace the second line with TileTable = ImageLoader.__loadTileTable('image path', some other variable) then i get NameError: name 'ImageLoader' is not defined
As i'm going from C# to Python, static classes with static methods is what i'd use to implement this. However, i'm open to how I'd do this in general in python (that is, call static library functions that are only grouped together by their functionality).
UPDATE:
After reading both answers, I'm getting a picture that what i'm trying to do probably isn't right.
How would I go about imlementing ImageLoader so that I can do this:
Assuming that tile table returned an array
module1.py
aTile = ImageLoader.TileTable[1]
module2.py
anotherTile = ImageLoader.TileTable[2]
ideally, i'd populate TileTable just once.
Update:
Thanks for all the answers, I found my last answer to populating TileTable just once in the python modules doco
"A module can contain executable
statements as well as function
definitions. These statements are
intended to initialize the module.
They are executed only the first time
the module is imported somewhere"
As for static class, i'm going to forgo classes and just make a module level variable.
Answering just the updated question, what you would do in Python is make TileTable a variable called tile_table in a module called imageloader. There is no reason at all to put any of this inside a class.
So then you get:
module1.py
import imageloader
aTile = imageloader.tile_table[1]
module2.py
import imageloader
anotherTile = imageloader.tile_table[2]
and imageload.py looks something like:
def _loadTileTable(arg1, arg2):
pass # blah blah
tile_table = _loadTileTable('image path', other_var)
Think of a Python module as a singleton instance in other languages (which in fact it is) and you'll be able to reconcile this with any OO preconceptions you inherited from other languages.
In Python, the code in the class block is first executed, then the resultant namespace is passed to the class initializer. The code you wrote could have also been written as:
TileTable = _loadTileTable(arg1, arg2)
#staticmethod
def _loadTileTable(arg1, arg2):
pass # blah blah
ImageLoader = type('ImageLoader', (), {'TileTable': TileTable, '_loadTileTable': _loadTileTable})
del TileTable
del _loadTileTable
As you can see, the call of _loadTileTable appears before the definition of it. In your example, within the class definition, the call to _loadTileTable must come after the definition of _loadTileTable.
One possible fix is to simply re-arrange the class definition.
class ImageLoader:
def _loadTileTable(arg1, arg2):
pass # blah, blah
TileTable = _loadTileTable('image path', other_var)
Note that I removed the 'staticmethod', because at the point where _loadTileTable is called, it's being called as a function and not a method. If you really want it to be available after class initialization, you can define it as a static method after the fact.
class ImageLoader:
def _loadTileTable(arg1, arg2):
pass # blah, blah
TileTable = _loadTileTable('image path', other_var)
_loadTileTable = staticmethod(_loadTileTable)
Class-level variables which get updated are a bad, bad thing. Our default expectation is that object instances are stateful and classes are stateless.
In this case, we're trying to "magically" initialize a collection as a class variable, which is a toweringly bad idea. A collection is simply an object with simple instance-level attributes.
The magical Tile Table should not be a concealed, static part of the ImageLoader. There is no possible reason for that. It should be an argument to the ImageLoader if you want to avoid loading it more than once.
Separating these promotes testability. It's not arbitrary. It's how unit testing gets done.
What you want is this.
class ImageLoader( object ):
def __init__( self, theTileTable ):
self.tile_table= theTileTable
class TileTable( object ):
def __init__( self, path, some_other_arg ):
self.tileTable= self._loadTileTable( path, some_other_arg )
def _loadTileTable(arg1, arg2):
blah blah
No static anything. Independent units. More easily testable. No weird dependencies. No magic.
Is there a design reason you're using a static method? If so, because you're not overloading the class initialization, you'll need to declare the variable after the method definition.
But, if you do this, you'lll get a new error:
NameError: name 'arg1' is not defined
The reason for this is because you're executing the method within the class before the class is even instantiated, therefore you never have a chance to pass the arguments to the method.
So, the proper way to do this is to overload the __init__() method so that assignment to TileTable only happens when the class is constructed:
class ImageLoader(object):
def __init__(self, arg1, arg2):
self.TileTable = self._loadTileTable(arg1, arg2)
#staticmethod
def _loadTileTable(arg1, arg2):
print arg1, arg2
This gives you the ability to call ImageLoader._loadTileTable() without having an instance, but then it also allows you to create the TileTable instance variable upon creating an instance.
Using a Class method
In response to my comment about the possible need for a classmethod, here is an example that covers this:
class ImageLoader:
#classmethod
def _loadTileTable(cls, arg1, arg2):
return arg1, arg2
# We're creating the class variable outside of the class definition. If you're doing
# this in a module, no one will ever notice.
ImageLoader.TileTable = ImageLoader._loadTileTable('foo', 'bar')
There might be a better way to do this, I don't know. But I do think that this covers what you are looking for:
>>> i = ImageLoader()
>>> i
<__main__.ImageLoader instance at 0x100488f80>
>>> ImageLoader.TileTable
('foo', 'bar')
>>> i.TileTable
('foo', 'bar')
There you have an instance i that has access to the class variable, but ImageLoader.TileTable is still available from the class object without the need for an instance.

Categories

Resources