python: how to get the class of a calling method through inspection? - python

For my exception class I'd like to find out whether the function which instantiated the exception object is a method and if so, show the class name.
So in the init method of my exception class I get the name of the calling function:
frame, module, line, function, context, index = inspect.stack()[1]
But is there any way the get the class name (if any) of the calling function?

Assuming the frame is for an instance method:
self_argument = frame.f_code.co_varnames[0] # This *should* be 'self'.
instance = frame.f_locals[self_argument]
class_name = instance.__class__.__name__

Related

Instantiating and Using a Method of a Class Within a Function

I'm trying to instantiate a class within a function, then call a method within the class inside the same function, like this:
# Define the class
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
# Define the function that utilizes the class
def func(class,func,str)
instance = class(str)
class = class.func()
# Run the function that utilizes the class
func(myclass,myclass_func,str)
But I am getting an error like "'myclass' object is not callable". Why is this? Additionally, I expect my 'class = class.func()' line is wrong; if it is, what is the correct way to call the method from the recently instantiated class?
Edit: fixed mistake in class declaration
You can't use method names as global variables. If you want to call a method dynamically, pass its name as a string and use the getattr() function.
# Define the class
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
# Define the function that utilizes the class
def func(class,func,str)
instance = class(str)
return getattr(instance, func)()
# Run the function that utilizes the class
func(myclass,'myclass_func',str)
Define your class using the class keyword rather than def.
Create an instance of the class.
Define a function that will try to execute the function given by its name.
class myclass:
def __init__(self,string_to_print):
self.string_to_print = string_to_print
def myclass_func(self):
print(self.string_to_print)
myclass_instance = myclass('Hello world')
def execute_function(instance, function):
getattr(instance, function)()
execute_function(myclass_instance, 'myclass_func')
Output:
Hello world

Why object's attributes are not there when the class is instantiated?

Why instantiating a class does not instantiate all its attributes ? I think a very simple example could explain my problem better:
class Example:
def example(self):
self.var=10
if __name__=='__main__':
E=Example()
# In this case, the attribute var is not instantiated
try:
attr=getattr(E,"var")
print(attr) # <-- it does not exist even if E instantiated Example class
except AttributeError:
print("Object not having this attribute") # <-- This is the output
Why the object E does not have all its attributes instantiated (namely the attribute var) ?
Unlike Java, in Python, the initiator function is called __init__; naming the method like the name of the class does not create a constructor.
So, when you instantiate an object of class Example, the method example is not called and your attribute doesn't exist. You'll have to call it explicitly, like this:
>>> e = Example()
>>> e.example()
>>> e.var
10
To have the attribute available to all objects at instantiation, modify your class and create a __init__ method, like this:
class Example:
def __init__(self):
self.var = 10
Now, it will work as you expect:
>>> e = Example()
>>> e.var
10
in your class if you need to initialize var you need to call it explicitly by calling the example method in the example class
but if if you write __init__ method it it automatically initialize the variable at the time of object creation
The init method (init for initialise) is called when the object is instantiated. Instantiation is done by (effectively) calling the
class.Here a new instance is created. Then its init method is called .it call the example method to initialize var in the exapme
class Example:
def __init__(self):
self.var=0 # or you can directly give self.var=10
self.example()
def example(self):
self.var=10
if __name__=='__main__':
E=Example()
# In this case, the attribute var is not instantiated
try:
attr=getattr(E,"var")
print(attr) # <-- it does not exist even if E instantiated Example class
except AttributeError:
print("Object not having this attribute")
other way of doing is
when you intalized class object call the method in it
E=Example()
E.example()#explicitly call example method in the class
You not called example method which sets var to self.
try
if __name__=='__main__':
E=Example()
E.example()
# In this case, the attribute var is not instantiated
try:
attr=getattr(E,"var")
print(attr)
except AttributeError:
print("Object not having this attribute")

Override the method index_html of a custom content type

I've a custom contentype. I need to override the base view of this objects only when is a anonymous user:
class Imagesblock(folder.ATFolder):
.......
def index_html(self):
""" use the parent view """
portal_state = getMultiAdapter((self, self.REQUEST), name="plone_portal_state")
if portal_state.anonymous()==True:
response = self.REQUEST.response
url = self.aq_parent.absolute_url()
return response.redirect(url, status=303)
else:
return super(Imagesblock).index_html()
I supposed to use the index_html of the super class, but I obtain an error:
AttributeError: 'super' object has no attribute 'index_html'
Any suggestions?
Vito
If you want to use the method index_html() from the superclass, you should call it with
folder.ATFolder.index_html(self)
assuming folder.ATFolder is the name of the superclass.
Edit:
As #Mathias mentioned, you also could call it as:
super(Imagesblock, self).index_html()

Python ImportError Keyword Argument

I have the following problem.
I want to have an object class, which takes as superclass a predefined object as keyword argument.
But I'm getting the error:
ImportError: cannot import name Object
Code:
import Object
class Object:
defaultobject = Object('defaultobject', None)
def __init__(self, name, superclass = defaultobject):
self.__name = name
self.__superclass = superclass
You cannot import the module you are in. You'll have to move the Object() instantiation to after the class definition:
class Object:
defaultobject = None
def __init__(self, name, superclass=None):
self.__name = name
if superclass is None:
superclass = self.defaultobject
if superclass is None
# No default set yet, use `self` instead (it'll *be* the default)
superclass = self
self.__superclass = superclass
Object.defaultobject = Object('defaultobject', None)
You can always add more attributes to a class definition, but to create an instance of a class you first need to have defined it.
The superclass is None dance is needed, because you otherwise have a catch-22 here; you cannot create an instance of Object without setting Object.defaultobject first. Which you cannot do, because you haven't created the default yet.
This issue can be solved by removing the import library from parent class which is also imported by some of its child classes. if your child class is also using import object then removing that from parent will solve the issue.

Referencing variable from static method inside another action in Pylons

I've got:
class ArticleController(SubbaseController):
def view(self):
c.referral = self.detect_referral.referrer
return render('/article.mako')
#staticmethod
def detect_referral():
referrer = request.META.get('HTTP_REFERRER', '')
I'm trying to reference the referrer inside of the view action from the detect_referral static method, but I keep getting: 'function' object has no attribute 'referrer' instead. Any ideas?
Also, is that the correct way to get the referrer?
You aren't returning the referrer from detect_referral, and detect_referral is not a property, so you cannot use that syntax.
class ArticleController(BaseController):
def view(self):
c.referral = self.detect_referral()
return render('/article.mako')
#staticmethod
def detect_referral():
return request.META.get('HTTP_REFERRER', '')
It's a local variable inside detect_referral(), and as such its lifetime is limited to the execution time of the method. Before the method is called and after the method returns local variables simply don't exist. (You don't even seem to call the method, so the local variable exists at no time of the execution of your program.)
Most probably you don't want a static method here. (You almost never want a static method in Python. I cannot remember that I ever used one.) Maybe all you need is a class attribute:
class ArticleController(SubbaseController):
referrer = request.META.get('HTTP_REFERRER', '')
def view(self):
c.referral = self.referrer
return render('/article.mako')
Note that the class body is executed once at class definition time.

Categories

Resources