Python: Call Method of Instance by another Instance - python

i want to call a method in an Instance by another new Instance like this:
class parentClass:
# Some methods here
class a:
def __init__(self, otherclass):
otherclass.__foo(a);
class b:
def __foo(self, firstclass):
#do something with firstclass
pClass = parentClass();
classB = pClass.b();
classA = pClass.a(classB);
But with this code i will get this kind of error:
AttributeError: b instance has no attribute '_a__foo'
I already tried to add this before method __foo():
#classmethod
But this still doesn't works.
Thanks for Help!

This is the simplest Solution:
Instead of
def __foo(self, firstclass):
i have to write
def foo(self, firstclass):
The double _ won't work here.
I will leave this Question & Answere at this place for other people with the same 'problem'.

Related

Finding parameters of `__init__()` or parameters needed to construct an object in python

I have scenario where I am passing a file name and checking if it has argument start as constructor if it has then I have to create instance of that class.
Consider the example where I have a file named test.py which have three class namely A,B,C now only class A has start parameter others have other different parameter or extra parameter.
#test.py
class A:
def __init__(self, start=""):
pass
class B:
def __init__(self, randomKeyword, start=""):
pass
class C:
def __init__(self):
pass
Now I want to write a script which takes test.py as an argument and create instance of A. Till now my progress is
detail = importlib.util.spec_from_file_location('test.py', '/path/to/test.py')
module = importlib.util.module_from_spec(detail)
spec.loader.exec_module(mod)
Bacially I need to write a program which finds init argument of all class in file and create an instance of file with start as init argument.
As mentioned by #deceze it's not a good idea to instantiate a class on the basis of it's init parameter as we're not sure what is there. But it's possible to do it. So I am posting this answer just so that you know how it can be done.
#test.py
class A:
def __init__(self, start=""):
pass
class B:
def __init__(self, randomKeyword, start=""):
pass
class C:
def __init__(self):
pass
One of the possibility is
#init.py
import importlib.util
from inspect import getmembers, isclass, signature
detail = importlib.util.spec_from_file_location('test.py', '/path/to/test.py')
module = importlib.util.module_from_spec(detail)
spec.loader.exec_module(module)
for name, data in getmembers(mod, isclass):
cls = getattr(mod, name)
parameter = signature(cls.__init__).parameters.keys()
# parameter start
if len(parameter) == 2 and 'start' in parameter:
object = cls(start="Whatever you want")
Ofcourse it's not the best approach so more answer are welcome and if you are in this scenario consider #deceze comment and define a builder.

How does Python support this common problem related to run time polymorphism?

I am trying to exectute the below code but I get errors.
class base:
def callme(data):
print(data)
class A(base):
def callstream(self):
B.stream(self)
def callme(data):
print("child ", data)
class B:
def stream(data):
# below statement doesn't work but I want this to run to achieve run time
# polymorphism where method call is not hardcoded to a certain class reference.
(base)data.callme("streaming data")
# below statement works but it won't call child class overridden method. I
# can use A.callme() to call child class method but then it has to be
# hardcoded to A. which kills the purpose. Any class A or B or XYZ which
# inherits base call should be able to read stream data from stream class.
# How to achive this in Python? SO any class should read the stream data as
# long as it inherits from the base class. This will give my stream class a
# generic ability to be used by any client class as long as they inherit
# base class.
#base.callme("streaming data")
def main():
ob = A()
ob.callstream()
if __name__=="__main__":
main()
I got the output you say you're looking for (in a comment rather than the question -- tsk, tsk) with the following code, based on the code in your question:
class base:
def callme(self, data):
print(data)
class A(base):
def callstream(self):
B.stream(self)
def callme(self, data):
print("child", data)
class B:
#classmethod
def stream(cls, data):
data.callme("streaming data")
def main():
ob = A()
ob.callstream()
if __name__=="__main__":
main()
Basically, I just made sure the instance methods had self parameters, and since you seem to be using B.stream() as a class method, I declared it as such.

how to start or call a function from a different class in python?

hey guys need to know as of how to start a method in a classA from class B
have
classA(object):
def __init__(self):
#this is where the ClassB method'' def multiplyPeople() ''should be called or started.
classB(object):
def multiplyPeople(self):
its giving an error
TypeError: unbound method multiplyPeople() must be called
with classB instance as first argument (got nothing instead)
know this is something basic, but am trying to figure out what exactly is supposed to be done and where am I getting lost.
I have called it as
classA(object):
def__init__(self):
self.PeopleVariable=classB.multiplyPeople()
It depends on how you want the function to work. Do you just want to use the class as a placeholder? Then you can use a so called static method for which you do not need to instantiate an object.
Or you can use a regular method and use it on a created object (notice that there you have access to self)
class A():
def __init__(self):
b = B()
b.non_static()
B.multiplyPeople()
class B():
#staticmethod
def multiplyPeople():
print "this was called"
def non_static(self):
print self, " was called"
if __name__ == "__main__":
a = A()
output:
<__main__.B instance at 0x7f3d2ab5d710> was called
this was called

Automatically fill a list in a class when I add a method in a subclass

Here is the context simplified:
class A(object):
def __init__(self):
self.vocab = [
('method1', self.method1),
('method2', 'arg2', self.method2),
('method3', self.method3),
]
class SubA(A):
def method4(self):
pass
def method5(self, arg5):
pass
class SubB(A):
def method6(self):
pass
def method7(self):
pass
I want to "automatically" fill self.vocab list from class A with all method from all subclasses and following the rule defined in self.vocab initialisation. So in this example I want to add method4,...,method7 automatically when object is instanciate.
So self.vocab becomes:
self.vocab = [
('method4', self.method4),
('method5', 'arg5', self.method5),
('method6', self.method6),
('method7', self.method7),
('method1', self.method1),
('method2', 'arg2', self.method2),
('method3', self.method3),
]
I think I have to change A into metaclass and use __new__ instead because I think it must be done before instanciation. In fact the class A is introspected by another code. self.vocab is extracted during instantiation and that's why I think it must be done before.
I don't know how to proceed and if it's possible.
The inspect module contains all tools that you need for this.
See this question how to get all methods of a class: How do I get list of methods in a Python class?
You can get your own current class in __init__ using self.__class__.
So, here is my solution. I changed initial setup a bit, though I tried to keep the original idea:
import inspect
class A(object):
vocab = set()
def __new__(cls, *args, **kwargs):
A.vocab.update(inspect.getmembers(cls, inspect.ismethod))
class SubA(A):
def method4(self):
pass
def method5(self, arg5):
pass
class SubB(A):
def method6(self):
pass
def method7(self):
pass
print A.vocab # set([])
SubA()
SubA()
SubB()
print A.vocab # set([('method5', <unbound method SubA.method5>), ('method6', <unbound method SubB.method6>), ('method4', <unbound method SubA.method4>), ('method7', <unbound method SubB.method7>)])
Actually inspect package can do every thing for you. you can use it like this..
inspect.getmembers(mod, inspect.isfunction) # returns all the members of the given module which are functions
But you can change the predicate such as isfunction, isclass, ismethod for bound methods etc.
Hope this helps :)

Python - how can I get the class name from within a class method - using #classmethod

I have the following code:
class ObjectOne(object):
#classmethod
def print_class_name(cls):
print cls.__class__.__name__
def print_class_name_again(self):
print self.__class__.__name__
if __name__ == '__main__':
obj_one = ObjectOne()
obj_one.print_class_name()
obj_one.print_class_name_again()
The output is:
type
ObjectOne
I would like the output to be:
ObjectOne
ObjectOne
But I would like to keep test_cls as a class method via the #classmethod decorator.
How can I accomplish this?
A classmethod receives the class as its argument. That's why you're calling it cls. Just do cls.__name__.
It's cls.__name__. cls already points to the class, and now you're getting the name of its class (which is always type).
I had a similar question and wantend to get the class name for logging and the function/method name.
__name__ : gives the program name
__class__.__name__ gives the class name
inspect.stack()[0][3] gives the module name. (you have to import inspect).
Cheers

Categories