Getattr for class objects

class A: def foo(self): print "foo()" getattr(A, foo) # True A.foo() # error getattr(A(), foo) # True A().foo() # prints "foo()" 

That being said, here is my problem:

I want to save the meta-information of the test case as attributes of the objects of the Test Case class themselves, and not on their instances.
I have a list of attribute names to retrieve, but if there is an instance method with the same name, getattr(class_obj, attr) will return True, but getattr(class_obj, attr)() throws an error.

Is there a way to tell getattr not to include the attributes of the created class and only the class object itself?

EDIT: I tried to access class_obj.__dict__ directly (which I understand is bad practice), but it does not include some attributes like __name__

EDIT: rephrase the question. Is there a way to differentiate obj class methods and class instance methods?

+4
source share
3 answers

Is this enough?

 import types class Test(object): @staticmethod def foo(): print 'foo' def bar(self): print 'bar' 

In conjunction with:

 >>>(isinstance(getattr(Test, 'foo'), types.FunctionType), isinstance(getattr(Test, 'bar'), types.FunctionType)) True, False 

You can also use the inspect module:

 >>> inspect.isfunction(Test.foo) True >>> inspect.isfunction(Test.bar) False 

With a little extra work, you can even distinguish class methods from instance methods and static methods:

 import inspect def get_type(cls, attr): try: return [a.kind for a in inspect.classify_class_attrs(cls) if a.name == attr][0] except IndexError: return None class Test(object): @classmethod def foo(cls): print 'foo' def bar(self): print 'bar' @staticmethod def baz(): print 'baz' 

You can use it like:

 >>> get_type(Test, 'foo') 'class method' >>> get_type(Test, 'bar') 'method' >>> get_type(Test, 'baz') 'static method' >>> get_type(Test, 'nonexistant') None 
+4
source

Your results are from an incorrect definition of foo , and not for any basic semantics of class attributes. By default, a function declared inside a class is an instance method that must take at least one argument, an instance of the class. It is usually called self :

 class A: def foo(self): print "foo()" 

You usually call this method as follows:

 a = A() a.foo() # passes the object 'a' implicitly as the value of the parameter 'self' 

but it is also legal.

 a = A() A.foo(a) # pass the object 'a' explicitly as the value of the parameter 'self' 

To define a function inside a class that does not accept any such implicit arguments, you need to decorate it with the @staticmethod decorator:

 class A: @staticmethod def foo(): print "foo()" 

Now you can call foo like you previously tried:

 >>> A.foo() foo() 
+3
source

You want something like this:

 from inspect import ismethod from collections import Callable def can_i_call(func): if not isinstance(func, Callable): # not a callable at all return False if not ismethod(func): # regular function or class or whatever return True # func is a method return func.im_self is not None 

Note. This only checks if the error will call if you call an unbound method without self . This does not guarantee that func() will succeed, i.e. Not for any other reason.

0
source

Source: https://habr.com/ru/post/1499494/


All Articles