How to call a function within a class with self - python

Suppose I have the following:
class myClass:
def foo(self):
# do something
How can I call myClass from inside the class without declaring an new myClass Object? i.e. I'd like something like
class myClass:
def foo(self):
# do something
if __name__ == '__main__':
# call foo
or without main:
class myClass:
def foo(self):
# do something
# call foo
Right now I keep getting either the error that self is not defined, or the error that foo expects 1 argument but 0 was provided.

You cannot. The function is part of the class, so to access it you must access the class first.
class myClass:
def foo(self):
# do something
myClass().foo()
If you just don't want to type myClass().foo() but only foo then you could just return the myClass() in a new function called foo():
def foo():
return myClass().foo()
You can use self in a class when calling from inside the class itself:
class myClass:
def __init__(self):
pass
def foo(self):
pass
def method2(self):
self.foo()
This does not create a new instance of myClass like calling myClass().foo() would, and you do not need to pass the same arguments that you may have passed in myClass.

Since foo() has a self parameter, that means it is an instance method, and therefore it is only callable from an instance of myClass.
If you want foo to be callable without an instance, use the #staticmethod decorator, and remove self from the parameter list.

Related

Why python class definition can refer to a concrete class instance name?

For example:
class abc:
def show(self):
print(self)
print(a)
a = abc()
a.show()
Here a is an instance of the class, which can be directly referred to in the method by its name, in addition to by the first argument self.
Why is this allowed?

how can i call static method from static method without using class name

Example of code:
How i run this code without using 'A'
class A:
#staticmethod
def a():
print('a')
#staticmethod
def b():
print('b')
print(**A**.a())
A.a()
you can refer the class with __class__.
try this:
class A:
#staticmethod
def a():
print('a')
#staticmethod
def b():
print('b')
__class__.a() # notice here we're not using `A`
A.b()
I think the only way might be to create a package, so a folder (e.g. src) containing an even empty _init_.py file, an A.py file containing your class and, above the folder, a main.py file containing the line
from src.A import *
then you can call
a()
without the class name
If you use the decorator #classmethod , an argument cls gets passed to the function which can refer to the classname without explicitly coding the class name, assuming you want to call this function from another static method of the same class. If the use case defers please say so as this is probably only a fit because you want to call it from a static method of the same Class.
class A:
#classmethod
def a(cls, args...):
pass
#classmethod
def b(cls, args...):
cls.a()
A.b() # notice that you dont need an instance of the class to call a class method only the class.

Refer to a class outside its method?

I need to deliver something like this in my program
class the_class_name(Parent):
the_attribute = self.parent_class_method()
#the parent class method will return a value
#but I cannot use self here since there's no self
How can I carry this out? Is there any other alternative that can do the job for me?
I have tried using __init__ like this:
def __init__(self):
Parent.__init__(self)
self.attribute = self.the_method()
But then I have problem creating the object, it won't receive any parameters that the Parent class normally receives anymore
Sounds like you are looking for __init__:
class TheClassName(Parent):
def __init__(self):
# Set attribute to the result of the parent method
self.attribute = super(TheClassName, self).the_method()
EDIT
If your parent class has parameters in it's own __init__ function, include them in the child class:
class Parent(object):
def __init__(self, foo, bar):
...
#classmethod
def the_method(cls):
...
class TheClassName(Parent):
def __init__(self, foo, bar):
super(TheClassName, self).__init__(foo, bar)
self.attribute = super(TheClassName, self).the_method()
I don't quite understand why you don't just call the parent method on your child object when you need the value though.
There is no self at that point of the creation of the subclass, nor is there an instance of the Parent class. That means the only Parent class methods you could call would have to be either static or class methods.
To demonstrate:
class Parent(object):
#staticmethod
def static_method():
return 42
#classmethod
def class_method(cls):
return 43
class TheClassName(Parent):
the_attribute = Parent.static_method()
another_attribute = Parent.class_method()
print(TheClassName.the_attribute) # -> 42
print(TheClassName.another_attribute) # -> 43
You must use class methods, declared with the #classmethod decorator, or a #staticmethod. The #classmethod decorator is preferable so that inheritance is handled correctly, i.e. the method is invoked on the derived class (a bit of a technicality, if you are still learning this).
class Alpha(object):
#classmethod
def method1(cls):
return 'method1 has been called on {}'.format(cls)
class Beta(Alpha):
def __init__(self):
self.myattr = Beta.method1()
print(Beta().myattr)
method1 has been called on class <'__main__.Beta'>
Use
super(ClassName, self).methodname(arg)
inside a method
def child_method(self, arg):
super(ClassName, self).methodname(arg)
You cannot use self outside a method.

Inheritance and accessing parent class in unbound method in python

I have this class with an unbound method and a static class inside:
class ClassA():
class Foo():
pass
def getFoo():
return ???.Foo
Now, if I inherit a ClassB from ClassA how do I get ClassB.getFoo() to return ClassB.Foo without explicitly implementing ClassB.getFoo()? Returning super().Foo doesn't work, writing ClassA.Foo doesn't work either obviously.
Your getFoo should be a classmethod:
class ClassA():
class Foo():
pass
#classmethod
def getFoo(cls):
return cls.Foo
Class methods are passed their class as their first argument, similar to how instance methods are passed the instance as the first argument. When you subclass ClassA, the proper class is passed.
Just to add my own thoughts on this: In addition to #Ned Batchelder's answer, you can use static methods to achieve a similar goal.
class ClassA():
class Foo():
def fooTest(self):
print("Hello from {}!".format(self.__name__))
#staticmethod
def getFoo():
return ClassA.Foo
class ClassB(ClassA):
pass
And test with:
>>> Foo = ClassB.getFoo()
>>> foo = Foo()
>>> foo.fooTest()
Hello from Foo!
This to me demonstrates the beauty of the python language - there are usually multiple ways of solving the same problem...

Not able call a local method from setUpClass

My code:
class TestSystemPromotion(unittest2.TestCase):
#classmethod
def setUpClass(self):
...
self.setup_test_data()
..
def test_something(self):
...
def setup_test_data(self):
...
if __name__ == '__main__':
unittest2.main()
Error which I'm getting is:
TypeError: unbound method setup_test_data() must be called with TestSystemPromotion
instance as first argument (got nothing instead)
You can't call instance methods from class methods. Either consider using setUp instead, or make setup_test_data a class method too. Also, it's better if you called the argument cls instead of self to avoid the confusion - the first argument to the class method is the class, not the instance. The instance (self) doesn't exist at all when setUpClass is called.
class TestSystemPromotion(unittest2.TestCase):
#classmethod
def setUpClass(cls):
cls.setup_test_data()
#classmethod
def setup_test_data(cls):
...
def test_something(self):
...
Or:
class TestSystemPromotion(unittest2.TestCase):
def setUp(self):
self.setup_test_data()
def setup_test_data(self):
...
def test_something(self):
...
For better comprehension, you can think of it this way: cls == type(self)

Categories