Calling an instance method without creating an instance of class in Python - python

I read on that instance methods can only be called by creating an instance (object) of the class. But it appears that I can call one without doing so. Check the code below:
class Test:
def func(self): #Instance Method
print(6)
Test.func(Test) # Here I am calling an instance method without creating an instance of class. How?
Please let me know what is happening behind the scenes.

Your code works because you feed as self argument the class itself.
Your function will work as long as you use self as class type and not as class instance, which is very bad practice.
I suggest to use staticmethods for such purposes:
class Test:
#staticmethod
def func():
print(6)
Test.func()
or #classmethod:
class Test:
#classmethod
def func(cls):
print(6)
Test.func()
Output:
6

Related

correct way of extending a class in python

I am given a designated factory of A-type objects. I would like to make a new version of A-type objects that also have the methods in a Mixin class. For reasons that are too long to explain here, I can't use class A(Mixin), I have to use the A_factory. Below I try to give a bare bones example.
I thought naively that it would be sufficient to inherit from Mixin to endow A-type objects with the mixin methods, but the attempts below don't work:
class A: pass
class A_factory:
def __new__(self):
return A()
class Mixin:
def method(self):
print('aha!')
class A_v2(Mixin): # attempt 1
def __new__(cls):
return A_factory()
class A_v3(Mixin): # attempt 2
def __new__(cls):
self = A_factory()
super().__init__(self)
return self
In fact A_v2().method() and A_v3().method() raises AttributeError: 'A' object has no attribute 'method'.
What is the correct way of using A_factory within class A_vn(Mixin) so that A-type objects created by the factory inherit the mixin methods?
There's no obvious reason why you should need __new__ for what you're showing here. There's a nice discussion here on the subject: Why is __init__() always called after __new__()?
If you try the below it should work:
class Mixin:
def method(self):
print('aha!')
class A(Mixin):
def __init__(self):
super().__init__()
test = A()
test.method()
If you need to use a factory method, it should be a function rather than a class. There's a very good discussion of how to use factory methods here: https://realpython.com/factory-method-python/

Learning Python: implementing a virtual method

First day learning Python, please excuse the basic question.
Assuming I have been given an object which contains an unimplemented method that I need to implement, e.g:
class myclass():
def __init__(self)
self.unimplementedmethod = False
What is the correct way to implement this in an instantiated object? I do not want to alter the base class in any way.
I have experimented and found the following code seems to work, but is it correct/good style?
def methodimplementation():
print("method called")
myobject = myclass()
myobject.unimplementedmethod=methodimplementation
Is this the right path? Or should I be doing something different like perhaps creating a derived class first, implementing the methods in it, and then instantiating an object based on the derived class? What is best practice?
You need to subclass the base class:
class myclass():
def some_method():
raise NotImplementedError
class my_subclass(myclass):
def some_method():
print("method called")
You want to create a abstract base class. For that, you need to inherit abc.ABCMeta in your base class. Then defining the method as abstract, you need to decorate it with #abstractmethod. For example:
from abc import ABCMeta, abstractmethod
class BaseClass(ABCMeta):
#abstractmethod
def my_method():
pass
Then you may create the child class as:
class MyChildClass(BaseClass):
def my_method():
print 'my method'
The good way is using subclasses, but if you can't do it, here is a way to access to self from a simple function not defined in a class:
class Bar:
def __init__(self):
pass
def foo(self):
try:
self._foo(self)
except AttributeError:
raise NotImplementedError
def set_foo(self, function):
setattr(self, '_foo', function)
def another_method(self):
print "Another method from {}".format(self)
def foo(self):
self.another_method()
bar = Bar()
bar.set_foo(foo)
bar.foo()
So, def foo(self) define a function with a single argument self, like a method. This function call a instance method another_method.
Bar.set_foo create a new attribute _foo in instance of Bar.
Finally, Bar.foo try to access to self._foo with self as argument. If _foo is do not exists, Bar.foo will raise a NotImplementedError as expected.
Like it you can access to self from foo without subclasses.

How to use method of one class to another class in different files in python

I am quite new to python, so pardon me for basic question. I tried google for past few days but could not make it in my program.
Can anyone show me a good example how can I use method from One class to another in python and what is significance of __init__ while defining class.
I am using python2.7
Thanks in anticipation.
To use a method defined in one class inside of another class, you have several options:
Create an instance of B from within one of A's methods, then call B's method:
class A:
def methodInA():
b = B()
b.methodInB()
If appropriate, use the concept of inheritance (one of the defining concepts of object-oriented design) to create a subclass of the original class whose method(s) you wish to use:
class B(A):
...
__init__() is a class initializer. Whenever you instantiate an object you are invoking __init__() whether or not it is explicitly defined. It's main purpose is to initialize class data members:
class C:
def __init__(self, name):
self.name = name
def printName(self):
print self.name
c = C("George")
c.printName() # outputs George
With __init__() defined, in particular with the additional argument name in this example, you are able to differentiate between would-be generically constructed instances by allowing for different initial states from instance to instance.
There are 2 issues here:
First: Using method of class A in class B, both classes in different files
class A:
def methodOfA(self):
print "method Of A"
let the above class be in file a.py Now the class B is supposed to be in b.py. Both a.py and b.py are assumed to be on the same level or in the same location. Then b.py would look like:
import a
class B:
def methodOfB(self):
print "Method of B"
a.A().methodOfA()
You can also do this by inherting A in B
import a
class B(a.A):
def methodOfB(self):
print "Method of B"
self.methodOfA()
there are several other ways to use A in B. I will leave it to you to explore.
Now to your second question. The use of __init__ in a class. __init__ is not a constructor, as popularly believed and explained above. It is, as the name suggests, an initialization function. It is called only after the object has already been constructed and it is implicitly passed the object instance as the first argument, as signified by self in its argument list.
The actual constructor in python is called __new__, which does not need a object to call it. This is actually a specialized Static method, which receives the class instance as the first argument. __new__ is exposed for overwriting only if the class inherits form the object base class of python
Whatever other arguments are passed while creating an object of a class, first go to __new__ and then are passed with the object instance to the __init__, if it accepts them.
The init function is what is called a constructor function. When you create an instance of a class object = myClass(), init is the function that is automatically called. i.e.
That being said, to call a function from one class to another, you need to call an instance of the second class inside the first one, or vice versa. for eg.
class One():
def func(self):
#does sometthing here
class Two():
def __init__(self):
self.anotherClass = One()
#Now you can access the functions of the first class by using anotherClass followed by dot operator
self.anotherClass.func()
#When you call the main class. This is the time the __init__ function is automatically called
mainClass = Two()
Another way to access from another class is the use of oop concept called Inheritance.
class One():
def __init__(self):
print('Class One Called')
def func(self):
print('func1 Called')
class Two(One):
def __init__(self):
One.__init__(self,) #This basically creates One's instance
print('Main Called')
c= Two()
c.func()
The output for this is:
Class One Called
Main Called
func1 Called

How to call function that is in the other class python for pytest

I am trying to call the methods in CSVDatasource in my testing class by typing this code from ETL.CSVDatasource import CSVDatasource and to call the necessary methods but I have been receiving errors like TypeError: unbound method preprocess_col() must be called with CSVDatasource instance as first argument (got DataFrame instance instead)
http://imgur.com/8sfygtA -> Image of my coding path
Anyone can guide me on calling out the method in the other class so that I can call the method and do testing in my testing classs?
Thanks.
Generally, an instance of the class has to be created before calling the method of the class. For example,
class Person:
def __init__(self,name):
self.name=name
def who(self):
print 'I am {}'.format(self.name)
#staticmethod
def species():
print 'I am human.'
If we want to call the method who inside the class Person, we have to create an instance of class as follows:
if __name__=='__main__':
p1=Person('Qing Yong')
p1.who() #I am Qing Yong
However, if a method doesn't require self but you want to put it inside the class as this method may strongly related to you class in some senses. You may declare it as static method by using the decorator #staticmethod, like the method species
This static method can be called either through instance or through class directly as follows.
if __name__=='__main__':
p1.species() #I am human.
Person.species() #I am human.
Depending on the context of your code, you may choose either way to use the method inside your class.

Call a function inside a class when calling the class in python

This simple example is what I dont get to work or understand in my more complex script:
class printclass():
string="yes"
def dotheprint(self):
print self.string
dotheprint(self)
printclass()
When the class is called, I expected it to run the function, but instead it will tell me that "self is not defined". Im aware this happens on the line:
dotheprint(self)
But I dont understand why. What should I change for the class to run the function with the data it already has within? (string)
You misunderstand how classes work. You put your call inside the class definition body; there is no instance at that time, there is no self.
Call the method on the instance:
instance = printclass()
instance.dotheprint()
Now the dotheprint() method is bound, there is an instance for self to refer to.
If you need dotheprint() to be called when you create an instance, give the class an __init__ method. This method (the initializer) is called whenever you create an instance:
class printclass():
string="yes"
def __init__(self):
self.dotheprint()
def dotheprint(self):
print self.string
printclass()
You really need to understand Object-Oriented Programming and its implementation in Python.
You cannot "call" a class like any function. You have to create an instance, which has a lifetime and methods linked to it :
o = printclass() # new object printclass
o.dotheprint() #
A better implementation of your class
class printclass():
string="yes" #beware, this is instance-independant (except if modified later on)
def dotheprint(self):
print self.string
def __init__(self): # it's an initializer, a method called right after the constructor
self.dotheprint()

Categories