Calling functions from different Classes in Python - python

I'm relatively new in python and I have the following question, my code looks something like this:
class Hkprop:
def hkprop_f(self):
hkprop= self.Mkprop().fun2() + self.Fkprop().fun4()
return hkprop
class Fkprop:
def fun1(self):
#something
def fun2(self):
self.fun1()
class Mkprop:
def fun3(self):
#something
def fun4(self):
self.fun1() #here I want to call fun1 but I don't know if it is possible or how to do it
I know this might be a super basic question, but if someone could help me I would really appreaciate it. I've been looking and came across #staticmethod, but I didn't completely understand. Is there a way of calling the function without using it?

If you want to call fun1, you can do Hkprop.Fkprop.fun1()

Yes, this is basic but sometimes, even such basic questions takes a little time to figure it out. So, I am assuming that your indentations are correct, and you have nested classes. Here is the solution that I did.... Hope this is helpful to you...
You will need to use the class inheritance methodolody, or simply learn how to instantiate class objects from one class to another as shown below.
When you save this code to a file a run it. You will see that first it will instantiate Hkprop.Mkprop and the call fun4. The next thing, we have done is instantiate Hkprop.Fkprop in func4 to be able to call func1 in FKprop class.
class Hkprop:
def hkprop_f(self):
hkprop= self.Mkprop().fun2() + self.Fkprop().fun4()
return hkprop
class Fkprop:
def fun1(self):
print('I just called this function')
def fun2(self):
self.fun1()
class Mkprop:
def fun3(self):
print('this is soemthing')
def fun4(self):
fk = Hkprop.Fkprop()
fk.fun1()
if __name__ == '__main__':
mk = Hkprop.Mkprop()
mk.fun4()

Let's breakdown your code. You wrote:
def fun4(self):
self.fun1()
There are 2 problems here.
self represents the instance of the class. Since, Mkprop class has no defintion of fun1() so it cannot access fun1()
fun1() function also expects a parameter in Fkprop class
In fun4, if you want to call fun1() then make the following change:
def fun4(self):
Hkprop.Fkprop.fun1(self)
Moreover, in python, functions cannot have empty body. Your current code will get the error:
IndentationError: expected an indented block
Because the interpreter expects a function body that is indented. To keep the empty functions, change fun1 & fun3 functions like this
def fun1():
pass
def fun3():
pass
pass is a special statement in Python that does nothing. It only works as a dummy statement.

I never tried nested classes before. In your case, it seems like you're calling a nonexistent function from a class. fun1() does not exist in class Mkprop.
If you want to call fun1(), you have to call it from it's respective class, therefore, Hkprop().Fkprop().fun1(). It goes something like this: Parent Class -> Sub class -> Function.

Related

Why is a method of a Python class declared without "self" and without decorators not raising an exception?

I thought that the following code would result in an error because as far as I have read, a method in a Python class must either have "self" (or any other label, but "self" by convention) as its first argument, or "cls" or similar if the #classmethod decorator is used, or none if the #staticmethod decorator is used.
How come I get no error running this with Python 3.5 in the Terminal, even though test_method does not meet these requirements? It seems to work fine as a static method, but without the decorator.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
class MyClass:
def test_method(args):
print(args[1])
#staticmethod
def static_method():
print("static_method")
#classmethod
def class_method(cls):
print("class_method")
def main(args):
MyClass.test_method(args)
if __name__ == '__main__':
sys.exit(main(sys.argv))
Output:
$ python3 testscript.py "testing"
$ testing
EDIT:
My question could also be phrased differently, drawing attention away from self and to #staticmethod: "How come I'm getting a seemingly working static method without the #staticmethod decorator?"
In Python 2, functions defined in a class body are automatically converted to "unbound methods", and cannot be called directly without a staticmethod decorator. In Python 3, this concept was removed; MyClass.text_method is a simple function that lives inside the MyClass namespace, and can be called directly.
The main reason to still use staticmethod in Python 3 is if you also want to call the method on an instance. If you don't use the decorator, the method will always be passed the instance as the first parameter, causing a TypeError.
There is nothing special about this. In python 3 there is no difference between a function defined inside a class or a function defined outside a class. Both of them are normal functions.
The self that you are talking about here or maybe cls comes into picture only when you access the function through an instance. Hence here you didn't get any error.
However if you modify your code just a little bit to look like the following, then you'd get an error that you expected.
def main(args):
MyClass().test_method(args)
# Should throw an error
EDIT:
#staticmethod will work on both class instances like MyClass().test_method(args)and just a regular direct call like MyClass.test_method(args)
However a regular method(without self in it) can't be called on a class instance. So you will always have to call it as MyClass.test_method(args)
self isn't necessarily required. However, if you want to reference any variable or value that is associated with the object(instantiation of the class) (E.g. for a class about cars, it's speed, self.speed) you'll need to have self as a parameter in the function. For this reason, it's common practice to always have self as an argument, otherwise you aren't really using the class for the right reason.
EDIT:
This will actually throw an error if you do the following:
class a():
def __init__(self, x):
self.asd = x
def hello(x):
print(x)
>>> g = a(4)
>>> g.hello(5)
as when calling "hello", both "self" and "4" will be passed as parameters. It would work in the following instance, which is what I was saying above:
>>> g = a
>>> g.hello(4)
or
>>> a.hello(4)
To add on to the existing answers here and provide a code example:
class MyClass:
def __init__(self):
pass
def myStaticMethod():
print("a static method")
#staticmethod
def myStaticMethodWithArg(my_arg):
print(my_arg)
print("a static method")
MyClass.myStaticMethod()
MyClass.myStaticMethodWithArg("skhsdkj")
abc = MyClass()
abc.myStaticMethodWithArg("avc")
Try removing the #staticmethod decorator and rerunning the code and see what happens! (The very last call will fail since the method is passed in both self and the string input. By adding the decorator, we can guide the interpreter to perform our desired action)

Why does this class run?

I've been playing with my codes a little for a while, and this one is not about a bug or anything, but i just don't understand why class main() runs without needing to initialize it...
class vars():
var1 = "Universe!"
var2 = "Oscar!"
var3 = "Rainbow!"
class main():
print (vars.var1)
def __init__(self):
print (vars.var2)
print (vars.var3)
But yes, thank you very much for reading.
Unlike many other languages, class body is an executable statement in Python and is executed immediately as the interpreter reaches the class line. When you run this "program":
class Foo:
print("hey")
it just prints "hey" without any Foo object being created.
The same applies to the function definition statement def (but not to function bodies). When you run this:
def foo(arg=print("hi")):
print("not yet")
it prints "hi", but not "not yet".
When a class is created, Python executes all of the code directly inside the class declaration in a new namespace. This is so that any variables created in the class (most commonly methods, created by ordinary function declarations like def foo(self...)) are attached to the class rather than being global.
But the code still runs immediately. If it calls print() or does something else which creates a visible side effect, that will happen now, not when the class is instantiated (called to create a new instance). If you need something to happen when the class is instantiated, write an __init__() method instead.
main is a class not a function. Thus the code contained in the class declaration runs immediately because all statements are executed as they appear in code. As a method declaration is reached, it's bound to the class as a member, so in a way methods execute as well but are not called.
When Python read your code, it looked into class vars and defined all the variables. Then, it went into class main and executed the code there, as well as defining init. Python just executes whatever which is not in a function definition.

PYTHON: AttributeError - calling function in a member function of a class

I'm having trouble with classes in Python 2.7:
First, I really do not know how to use the __init__ properly, so I have just used a dummy call to print. What should I do instead?
Second, I would like the member function readAnyFormat to call a few functions (later I will create a kind of case statement). My attempt produced an AttributeError. How do I do this correctly?
My class is as follows:
class ArangeData:
def __init__(
self):
print ' '
def readAnyFormat(
self,
config = True,
mypath='text.txt',
data_format='ASCII',
data_shape='shaped'):
#Here the function should be called:'
#NOT WORKING:
#AttributeError: ArangeData instance has no attribute 'readASCII'
if data_format=='HDF5':
readHDF5()
elif data_format=='ASCII':
readASCII()
def readASCII():
'doing stuff in here'
def readHDF5():
'doing other stuff in here, which is not the business of readASCII'
def otherMemberFunction(self):
'do not care what they are doing above!'
You should move the definition of readASCII and readHDF5 so they are above the two if statements.
You don't need to have the dummy print statement in __init__. If you have nothing to initialize you can simply use pass, or better yet as #chepner commented don't even define __init__.

How to call function from class in python, answer must be in links but dont get it

Im using a function I downloaded somewhere however its not a function but a class and I have no clue how to call it. This is aproximately how it looks, say this is examplefile.py:
class exampleclass:
somevar = 1
def func1(self, input):
return input+somevar
def func2(self, input):
return input-somevar
def main():
hardvar = 2
examp = exampleclass()
out1 = examp.func1(hardvar)
out2 = examp.func2(hardvar)
print(hardvar,out1,out2)
if __name__ == "__main__"
main()
I just dont get how to use the functions inside of it. I tried
import examplefile
import exampleclass
from examplefile import exampleclass
some of these do import the class, then I try calling it like this
exampleclass.func1(1)
or
exampinstance= exampleclass
exampinstance.func1(1)
which both get me
TypeError: unbound method ...() must be called with ... instance as first argument (got list instance instead)
and thats what never works, I looked at several questions (such as these) here but I just dont get how it works. Maybe you guys can see what Im not getting.
I call you to look at the following link. It may help:
How to instantiate a class in python
However you are nearly there. The code would look something like:
exampinstance= exampleclass()
exampinstance.func1(1)
Note the () at the end of the first line. You need to instantiate the class properly. Note how the class is instantiated in the Main Method of the file itself.

Python 3: Calling a Function from a class, self

I am trying to learn about classes, can someone explain to me why this code is not working. I thought when calling a function from a class, "self" is automatically ommitted, but the interpreter tells me that argument "a" is missing (he thinks self = 10).
#! coding=utf-8
class test:
def __init__(self):
"do something here"
def do(self,a):
return a**2
d = test.do
print(d(10))
Instantiate the class first:
d = test().do
print(d(10)) # prints 100
test.do is an unbound method, test().do is bound. The difference is explained in this thread: Class method differences in Python: bound, unbound and static.
You have to instantiate the class first:
d = test()
then you can call a method:
print(d.do(10))
if you want to use method statically you have to declare it in python
#! coding=utf-8
class test:
def __init__(self):
"do something here"
#staticmethod
def do(a):
return a**2
d = test.do
print(d(10)) #and that's work
Since you haven't instantiated the class (a fancy term for created) you can't be assigning methods to any random variable. Like already said, you must create the object first, whilst making sure the method you call is a part of the class you called or connected to the class in some way (such as creating another class and then communicating that class with the current class). So you should first type d=test() followed by d.do().
Also, remember that in your declaration of the method you crated a parameter so what you done was wrong in itself anyway, because when you declared the do function, you should have put within the brackets the number you wanted to send to the method to calculate its square. So you type test.do(10) and then the 10 is sent by the self reference to the method to be done whatever it is you told it to do.
One more thing: although it isn't a huge deal, it helps if all of your class names begin with a capital letter, as this is usually the 'pythonic' way to do things, and it also makes your code much easier to read, because when you first called the class, somebody could easily mistaken it for an ordinary function
class test:
def __init__(self):
"do something here"
def do(self,a):
return a**2
def __call__(self,a):
return self.do(a)
a = test
test.do(a,10)
#or
a = test().do
a(10)
#or
a = test()
test.do(a,10)
#or
a = test()
print(a(10))

Categories