Python create object and access class method at the same time - python

The object is created by a = Foo(), the object can be nested with a.b, after that I can perform a.b.bar() to print("Hello World")
class Foo:
def bar():
print("Hello World")
def __getattr__(self, name):
setattr(self,name,Foo)
The problem is I need to first use a.b to create an object first, then only I can do a.b.bar(), is there a way that I could do a.b.bar() straightaway to create the object and access the bar() at the same time?

Related

Get the object that a function was called from in python

If I have a class that contains a method, and I call that method from an instance, how do I get the specific instance it was called from?
e.g. I have a class:
class foo:
def __init__(self):
pass
def do_something(self):
bar()
I also have a function:
def bar():
print()
If i make an object, e.g. obj = foo(), and then i call obj.do_something(), How would i get obj from inside my bar() function?
Using the inspect module, you can get the caller frame and access its local variables, in particular the self argument representing the instance:
import inspect
def bar():
caller = inspect.stack()[1].frame
localvars = caller.f_locals
self = localvars['self']

How to write string based dynamic function dispatch in python from within a class?

I want to dynamically determine function dispatch in my python code.
Like so :
https://docs.python.org/3/faq/programming.html#how-do-i-use-strings-to-call-functions-methods
I build a dispatch dictionary wherein:
dispatch = {'foo' : foo_function, 'bar': bar:function}
And then from within code, I can call the appropriate function based on my data string by saying:
dispatch[data]()
So far so good. My issue is I want this functionality inside a class accessible to it's methods:
class Demo(object):
""" Demonstrate the issue
"""
dispatch = {'foo' : self.call_foo, 'bar': self.call_bar}
def parse_component(self, data, some_param):
self.__class__.dispatch[data](self, some_param)
def call_foo(self, some_param):
""" Do some intelligent work here"""
pass
def call_bar(self, some_param):
""" Do some intelligent work here"""
pass
The problem is that dispatch table is a class variable and does not have a notion of the instance methods self.call_foo and self.call_bar.
I tried using get_attr :
class Demo(object):
dispatch = {'foo': getattr(Demo, 'call_foo')}
I get a NameError on Demo with this. It does not recognize the class name from within the class which I guess makes sense.
Other than making dispatch another instance method, is there any other way to do this?
Ideally dispatch should be a class variable/method since it is constant to the class.
The functions Demo.call_foo and Demo.call_bar are functions which take in an instance self and some_param. When you create an instance of Demo, e.g. d = Demo(), those functions now become bound methods where the self parameter is already passed for you. But the other form still exists, so you can call instance methods with ClassName.method(instance, ...). For example:
class Demo:
def call_foo(self):
print("called foo")
Calling it both ways works:
>>> d = Demo()
>>> Demo.call_foo(d)
called foo
>>> d.call_foo()
called foo
This is relevant to your question because inside the class definition, you don't have an instance self to use, but you can refer to the functions directly. Since they are functions defined in the class scope, they can be referenced directly like any other class attribute.
But like we've seen above, you can pass the instance along to the function. You're already doing that in parse_component. So the only problem with your current code is that you tried to use self to reference the methods. But since the dict is defined in the class scope, you can just refer to them by name:
class Demo:
def parse_component(self, data, some_param):
self.__class__.dispatch[data](self, some_param)
def call_foo(self, some_param):
print("called foo with", some_param)
def call_bar(self, some_param):
print("called bar with", some_param)
dispatch = {'foo' : call_foo, 'bar': call_bar}
And using it:
>>> d = Demo()
>>> d.parse_component("foo", 2)
called foo with 2
>>> d.parse_component("bar", 3)
called bar with 3
>>> Demo.parse_component(d, "foo", 4)
called foo with 4

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

Method of an object in Python

I was just pulling off a toy example for myself, but it is not working and I cannot make it work. Does anybody know why this is not working and how to make it work:
class A(object):
#def __init__():
#pass
def do1():
print("foo")
def do2():
print("Hello")
Al = A
Al.do1()
TypeError: unbound method do1() must be called with A instance as first argument (got nothing instead)
In your code variable A1 it's reference to your class not instance, create instance of your class
Al = A()
and run your method
Al.do1()
You need to call your class to crate a correct instance and pass the self keyword to enclosing function to provides a handle back to the instance to be processed :
class A(object):
#def __init__():
#pass
def do1(self):
print("foo")
def do2():
print("Hello")
Al = A()
Al.do1()
Note that without passing the self to your function after calling it you will get a TypeError.
TypeError: do1() takes 0 positional arguments but 1 was given
Or as #Padraic Cunningham mentioned in comment you can use staticmethod as a decorator to wrap your function which makes python doesn't pass the first default argument (self) to it.
class A(object):
#def __init__():
#pass
#staticmethod
def do1():
print("foo")
def do2():
print("Hello")
Al = A()
Al.do1()

Python - Exists a function that is called when an object does not implement a function?

In Smalltalk there is a message DoesNotUnderstand that is called when an object does not understand a message (this is, when the object does not have the message sent implemented).
So, I like to know if in python there is a function that does the same thing.
In this example:
class MyObject:
def __init__(self):
print "MyObject created"
anObject = MyObject() # prints: MyObject created
anObject.DoSomething() # raise an Exception
So, can I add a method to MyObject so I can know when DoSomething is intented to be called?
PS: Sorry for my poor English.
Here is a proposition for what you want to do:
class callee:
def __init__(self, name):
self.name = name
def __call__(self):
print self.name, "has been called"
class A:
def __getattr__(self, attr):
return callee(attr)
a = A()
a.DoSomething()
>>> DoSomething has been called
You are looking for the __getattr__ method. Have a look here.
If you want "total control" of a class, look at the __getattribute__ special method then (here).
Have you looked at object.__getattr__(self, name), or object.__getattribute__(self, name) for new-style classes? (see Special method names, Python language reference)
I don't know why luc had the two separate classes. You can do it all with one class, if you use a closure. Like so:
class A(object):
__ignored_attributes__ = set(["__str__"])
def __getattr__(self, name):
if __name__ in self.__ignored_attributes__:
return None
def fn():
print name, "has been called with self =", self
return fn
a = A()
a.DoSomething()
I added the bit about __ignored_attributes__ because Python was looking up __str__ in the class and that got a little messy.

Categories