Getting class attributes

I want to get class attributes, say:

class MyClass(): a = "12" b = "34" def myfunc(self): return self.a 

using MyClass.__dict__ gives me a list of attributes and functions and even functions like __module__ and __doc__ . So far, MyClass().__dict__ gives me an empty dict, unless I explicitly set the attribute value of this instance.

I just need the attributes in the above example: a and b

+60
python class attributes
Jan 30 2018-12-01T00:
source share
15 answers

Try the inspect module. getmembers and various tests should be helpful.

EDIT:

For example,

 class MyClass(object): a = '12' b = '34' def myfunc(self): return self.a >>> import inspect >>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))) [('__class__', type), ('__dict__', <dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>, '__doc__': None, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, 'a': '34', 'b': '12', 'myfunc': <function __main__.myfunc>}>), ('__doc__', None), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'MyClass' objects>), ('a', '34'), ('b', '12')] 

Now special methods and attributes are on my nerves - they can be solved in several ways, the simplest of which is only filtering based on the name.

 >>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a))) >>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))] [('a', '34'), ('b', '12')] 

... and more complex of which may include special attribute name checks or even metaclasses;)

+80
Jan 30 2018-12-01T00:
source share
β€” -
 def props(cls): return [i for i in cls.__dict__.keys() if i[:1] != '_'] properties = props(MyClass) 
+23
Jun 22 '13 at 9:31 on
source share

myfunc is the MyClass attribute. How it was found at startup:

 myinstance = MyClass() myinstance.myfunc() 

He searches for the myinstance attribute named myfunc , does not find it, sees that myinstance is an instance of MyClass and looks for it there.

Thus, a complete list of attributes for MyClass :

 >>> dir(MyClass) ['__doc__', '__module__', 'a', 'b', 'myfunc'] 

(Note that I use dir as a quick and easy way to list class members: it should be used only in search mode, not in production code)

If you need only certain attributes, you will need to filter this list using some criteria, because __doc__ , __module__ and myfunc are not special, they are attributes just like a and b .

I have never used the validation module referenced by Matt and Borealid, but from the short link it looks like it has tests to help you do this, but you need to write your own predicate function, since what you want seems to be this approximately those attributes that do not pass the isroutine test and do not begin and end with two underscores.

Also note: using class MyClass(): in Python 2.7, you are using completely outdated old-style classes. If you are not doing this specifically for compatibility with extremely old libraries, you should instead define your class as class MyClass(object): There are no "old style" classes in Python 3, and this is the default behavior. However, using the newstyle classes will give you a lot more automatically defined attributes:

 >>> class MyClass(object): a = "12" b = "34" def myfunc(self): return self.a >>> dir(MyClass) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'myfunc'] 
+17
Jan 30 '12 at 1:26
source share

MyClass().__class__.__dict__

However, the β€œright thing” was to do this through the verification module .

+6
Jan 30 2018-12-01T00:
source share

My decision is to get all the attributes (not methods) of the class (if the class has a correctly written documentation line in which the attributes are clearly indicated):

 def get_class_attrs(cls): return re.findall(r'\w+(?=[,\)])', cls.__dict__['__doc__']) 

This cls.__dict__['__doc__'] retrieves the cls.__dict__['__doc__'] class documentation.

+2
Oct 22 '15 at 10:13
source share
 import re class MyClass: a = "12" b = "34" def myfunc(self): return self.a attributes = [a for a, v in MyClass.__dict__.items() if not re.match('<function.*?>', str(v)) and not (a.startswith('__') and a.endswith('__'))] 

For an instance of MyClass, for example

 mc = MyClass() 

use type(mc) instead of MyClass in list comprehension. However, if one dynamically adds the mc attribute, for example mc.c = "42" , this attribute will not be displayed when using type(mc) in this strategy. It gives only attributes of the source class.

To get the full dictionary for an instance of a class, you need to CREATE dictionaries type(mc).__dict__ and mc.__dict__ .

 mc = MyClass() mc.c = "42" # Python 3.5 combined_dict = {**type(mc).__dict__, **mc.__dict__} # Or Python < 3.5 def dict_union(d1, d2): z = d1.copy() z.update(d2) return z combined_dict = dict_union(type(mc).__dict__, mc.__dict__) attributes = [a for a, v in combined_dict.items() if not re.match('<function.*?>', str(v)) and not (a.startswith('__') and a.endswith('__'))] 
+2
Oct 19 '16 at 23:14
source share

I don’t know if something similar was done now or not, but I made a good attribute search function using vars (). vars () creates an attribute dictionary of the class you are going through.

 class Player(): def __init__(self): self.name = 'Bob' self.age = 36 self.gender = 'Male' s = vars(Player()) #From this point if you want to print all the attributes, just do print(s) #If the class has a lot of attributes and you want to be able to pick 1 to see #run this function def play(): ask = input("What Attribute?>: ") for key, value in s.items(): if key == ask: print("self.{} = {}".format(key, value)) break else: print("Couldn't find an attribute for self.{}".format(ask)) 

I am developing a fairly large-scale Text Adventure in Python, my Player class has over 100 attributes. I use this to search for specific attributes that I need to see.

+2
Apr 24 '18 at 19:16
source share

I recently needed to find something similar to this question, so I wanted to post some background information that might be useful to others facing this in the future.

Here's how it works in Python (from https://docs.python.org/3.5/reference/datamodel.html#the-standard-type-hierarchy ):

MyClass is a class object, MyClass() is an instance of a class object. The __dict__ instance contains only attributes and methods specific to that instance (for example, self.somethings ). If an attribute or method is part of a class, it is in the __dict__ class. When you execute MyClass().__dict__ , an instance of MyClass is created with no attributes or methods other than class attributes, thus an empty __dict__

So, if you say print(MyClass().b) , Python will first check for a new instance of dict MyClass().__dict__['b'] and cannot find b . He then checks the MyClass.__dict__['b'] class and finds b .

To do this, you need the inspect module to emulate the same search process.

+1
Mar 09 '16 at 17:55
source share

Retrieving only instance attributes is easy. But getting class attributes without functions is a bit more complicated.

Instance Attributes Only

If you only need to specify the attributes of the instance , just use for attribute, value in my_instance . __dict__ . items()

 >>> from __future__ import (absolute_import, division, print_function) >>> class MyClass(object): ... def __init__(self): ... self.a = 2 ... self.b = 3 ... def print_instance_attributes(self): ... for attribute, value in self.__dict__.items(): ... print(attribute, '=', value) ... >>> my_instance = MyClass() >>> my_instance.print_instance_attributes() a = 2 b = 3 >>> for attribute, value in my_instance.__dict__.items(): ... print(attribute, '=', value) ... a = 2 b = 3 

Instance and class attributes

To get also class attributes without functions, the trick is to use callable() .

But static methods are not always callable !

So instead of using callable(value) use callable ( getattr ( MyClass, attribute))

Example

 from __future__ import (absolute_import, division, print_function) class MyClass(object): a = "12" b = "34" # class attributes def __init__(self, c, d): self.c = c self.d = d # instance attributes @staticmethod def mystatic(): # static method return MyClass.b def myfunc(self): # non-static method return self.a def print_instance_attributes(self): print('[instance attributes]') for attribute, value in self.__dict__.items(): print(attribute, '=', value) def print_class_attributes(self): print('[class attributes]') for attribute in MyClass.__dict__.keys(): if attribute[:2] != '__': value = getattr(MyClass, attribute) if not callable(value): print(attribute, '=', value) v = MyClass(4,2) v.print_class_attributes() v.print_instance_attributes() 

Note: print_class_attributes() must be @staticmethod
& EPRS; & EPRS; but not in this silly and simple example.

Result for python2

 $ python2 ./print_attributes.py [class attributes] a = 12 b = 34 [instance attributes] c = 4 d = 2 

Same result for

 $ python3 ./print_attributes.py [class attributes] b = 34 a = 12 [instance attributes] c = 4 d = 2 
+1
Jul 28 '17 at 16:21
source share

You can use dir() in list comprehension to get attribute names:

 names = [p for p in dir(myobj) if not p.startswith('_')] 

Use getattr() to get the attributes themselves:

 attrs = [getattr(myobj, p) for p in dir(myobj) if not p.startswith('_')] 
+1
Apr 13 '18 at 14:18
source share

I think this can be done without verification.

Take the following class:

  class Test: a = 1 b = 2 def __init__(self): self.c = 42 @staticmethod def toto(): return "toto" def test(self): return "test" 

Looking at the participants along with their types:

 t = Test() l = [ (x, eval('type(x.%s).__name__' % x)) for x in dir(a) ] 

... gives:

 [('__doc__', 'NoneType'), ('__init__', 'instancemethod'), ('__module__', 'str'), ('a', 'int'), ('b', 'int'), ('c', 'int'), ('test', 'instancemethod'), ('toto', 'function')] 

Thus, in order to output only the variables, you just need to filter the results by type, and the names do not start with '__'. for example

 filter(lambda x: x[1] not in ['instancemethod', 'function'] and not x[0].startswith('__'), l) [('a', 'int'), ('b', 'int'), ('c', 'int')] # actual result 

It.

Note: if you are using Python 3, convert iterators to lists.

If you want a more reliable way to do this, use inspect .

+1
Aug 21 '18 at 10:41
source share

two functions:

 def get_class_attr(Cls) -> []: import re return [a for a, v in Cls.__dict__.items() if not re.match('<function.*?>', str(v)) and not (a.startswith('__') and a.endswith('__'))] def get_class_attr_val(cls): attr = get_class_attr(type(cls)) attr_dict = {} for a in attr: attr_dict[a] = getattr(cls, a) return attr_dict 

use:

 >>> class MyClass: a = "12" b = "34" def myfunc(self): return self.a >>> m = MyClass() >>> get_class_attr_val(m) {'a': '12', 'b': '34'} 
0
Aug 23 '18 at 5:09
source share

You can use MyClass.__attrs__ . It just gives all the attributes of this class. Nothing more.

0
Feb 02 '19 at 1:21
source share

There is a very simple answer that should be obvious: getattr

 class MyClass(object): a = '12' b = '34' def myfunc(self): return self.a >>> getattr(MyClass, 'a') '12' >>> getattr(MyClass, 'myfunc') <function MyClass.myfunc at 0x10de45378> 

This works great in both Python 2.7 and Python 3.x.

If you want a list of these items, you will still need to use inspect.

-one
Jan 20 '18 at 13:07
source share

I know that this was three years ago, but for those who should come to this issue in the future, for me:

 class_name.attribute 

works great.

-3
Apr 20 '15 at 2:47
source share



All Articles