Python object get attr

What is getattr() exactly and how do I use it?

I read an article about the getattr function, but I still can’t understand what it’s for. The only thing I understand about getattr() is that getattr(li, «pop») is the same as calling li.pop . When and how do I use this exactly? The book said something about using it to get a reference to a function whose name isn’t known until runtime, but when and why would I use this?

@Alois, your answer definitely cleared some of my doubts, but I still can’t fully understand what getattr() is for.

@S.Lott, I did. The documentation only had the definition so I was kind of confused about its usage. I understand getattr now after reading more about it though.

14 Answers 14

Objects in Python can have attributes — data attributes and functions to work with those (methods). Actually, every object has built-in attributes (try dir(None) , dir(True) , dir(. ) , dir(dir) in Python console).

For example you have an object person , that has several attributes: name , gender , etc.

You access these attributes (be it methods or data objects) usually writing: person.name , person.gender , person.the_method() , etc.

But what if you don’t know the attribute’s name at the time you write the program? For example you have attribute’s name stored in a variable called attr_name .

gender = getattr(person, attr_name) 
Python 3.4.0 (default, Apr 11 2014, 13:05:11) >>> class Person(): . name = 'Victor' . def say(self, what): . print(self.name, what) . >>> getattr(Person, 'name') 'Victor' >>> attr_name = 'name' >>> person = Person() >>> getattr(person, attr_name) 'Victor' >>> getattr(person, 'say')('Hello') Victor Hello 

getattr will raise AttributeError if attribute with the given name does not exist in the object:

>>> getattr(person, 'age') Traceback (most recent call last): File "", line 1, in AttributeError: 'Person' object has no attribute 'age' 

But you can pass a default value as the third argument, which will be returned if such attribute does not exist:

You can use getattr along with dir to iterate over all attribute names and get their values:

>>> dir(1000) ['__abs__', '__add__', . '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes'] >>> obj = 1000 >>> for attr_name in dir(obj): . attr_value = getattr(obj, attr_name) . print(attr_name, attr_value, callable(attr_value)) . __abs__ True . bit_length True . >>> getattr(1000, 'bit_length')() 10 

A practical use for this would be to find all methods whose names start with test and call them.

Similar to getattr there is setattr which allows you to set an attribute of an object having its name:

>>> setattr(person, 'name', 'Andrew') >>> person.name # accessing instance attribute 'Andrew' >>> Person.name # accessing class attribute 'Victor' >>> 

So it seems to me that getattr(..) should be used in 2 scenarios: 1. when the attribute name is a value inside of a variable (e.g. getattr(person, some_attr) ) and 2. when we need to use the third positional argument for the default value (e.g. getattr(person, ‘age’, 24) ). If I see a scenario like getattr(person, ‘age’) it seems to me that it is identical to person.age which leads me to think that person.age is more Pythonic. Is that correct?

@wpcarro both person.age and getattr(person, «age») are idiomatic to Python, so hard to make the case one is more Pythonic than the other.

«Readability counts». Certainly person.age is better than getattr(person, «age») . I makes sense to use getattr when you have attribute name in a variable.

getattr(object, ‘x’) is completely equivalent to object.x .

There are only two cases where getattr can be useful.

  • you can’t write object.x , because you don’t know in advance which attribute you want (it comes from a string). Very useful for meta-programming.
  • you want to provide a default value. object.y will raise an AttributeError if there’s no y . But getattr(object, ‘y’, 5) will return 5 .

Am I incorrect in thinking that the second bullet point is inconsistent with opening statement of the answer?

@skoh: well, actually, the opening statement mentions getattr with two parameters (which is equivalent), and the 2nd bullet mentions getattr with 3 parameters. Even if it was incosistent though, I would probably leave it, emphasis is more important.

@UlfGjerdingen: think of javascript. o.x is equivalent to o[‘x’] . But the second expression could be used with any o[some_string] that could be decided at runtime (eg, from user input or object inspection), while in the first expression, x is fixed.

To revive a necro, another use case is when the identifier contains an illegal character like . or — (as I am dealing with now). getattr(obj, ‘some.val’) will work where obj.some.val will not.

@JürgenK.: of course, self behaves just like any other object, the only difference is that it’s passed automatically

For me, getattr is easiest to explain this way:

It allows you to call methods based on the contents of a string instead of typing the method name.

For example, you cannot do this:

obj = MyObject() for x in ['foo', 'bar']: obj.x() 

because x is not of the type builtin , but str . However, you CAN do this:

obj = MyObject() for x in ['foo', 'bar']: getattr(obj, x)() 

It allows you to dynamically connect with objects based on your input. I’ve found it useful when dealing with custom objects and modules.

@develarist The asker didn’t have an example for me to base my answer off of, so MyObject , obj , and x (Class def, class instance and attribute respectively) are just examples/mockup data where you should fill in your own classes and attributes that you want to access. foo , bar , and baz are often used as placeholders in linux/unix/foss docs.

operator.methodcaller( ) is designed to do the same as in this example, calling a method defined with strings. I kind of prefer the implementation in the example.

A pretty common use case for getattr is mapping data to functions.

For instance, in a web framework like Django or Pylons, getattr makes it straightforward to map a web request’s URL to the function that’s going to handle it. If you look under the hood of Pylons’s routing, for instance, you’ll see that (by default, at least) it chops up a request’s URL, like:

http://www.example.com/customers/list 

into «customers» and «list». Then it searches for a controller class named CustomerController . Assuming it finds the class, it creates an instance of the class and then uses getattr to get its list method. It then calls that method, passing it the request as an argument.

Once you grasp this idea, it becomes really easy to extend the functionality of a web application: just add new methods to the controller classes, and then create links in your pages that use the appropriate URLs for those methods. All of this is made possible by getattr .

Here’s a quick and dirty example of how a class could fire different versions of a save method depending on which operating system it’s being executed on using getattr() .

import os class Log(object): def __init__(self): self.os = os.name def __getattr__(self, name): """ look for a 'save' attribute, or just return whatever attribute was specified """ if name == 'save': try: # try to dynamically return a save # method appropriate for the user's system return getattr(self, self.os) except: # bail and try to return # a default save method return getattr(self, '_save') else: return getattr(self, name) # each of these methods could have save logic specific to # the system on which the script is executed def posix(self): print 'saving on a posix machine' def nt(self): print 'saving on an nt machine' def os2(self): print 'saving on an os2 machine' def ce(self): print 'saving on a ce machine' def java(self): print 'saving on a java machine' def riscos(self): print 'saving on a riscos machine' def _save(self): print 'saving on an unknown operating system' def which_os(self): print os.name 

Now let’s use this class in an example:

logger = Log() # Now you can do one of two things: save_func = logger.save # and execute it, or pass it along # somewhere else as 1st class: save_func() # or you can just call it directly: logger.save() # other attributes will hit the else # statement and still work as expected logger.which_os() 

Источник

Get all object attributes in Python? [duplicate]

Is there a way to get all attributes/methods/fields/etc. of an object in Python? vars() is close to what I want, but it doesn’t work unless an object has a __dict__ , which isn’t always true (e.g. it’s not true for a list , a dict , etc.).

4 Answers 4

note that the behavior of dir() is often manipulated to show interesting attributes, rather than strictly all; for instance it doesn’t show attributes inherited through a metaclass, or it may be overridden with a __dir__ method.

class MyObj(object): def __init__(self): self.name = 'Chuck Norris' self.phone = '+6661' obj = MyObj() print(obj.__dict__) print(dir(obj)) # Output: # obj.__dict__ --> # # dir(obj) --> ['__class__', '__delattr__', '__dict__', '__doc__', # '__format__', '__getattribute__', '__hash__', # '__init__', '__module__', '__new__', '__reduce__', # '__reduce_ex__', '__repr__', '__setattr__', # '__sizeof__', '__str__', '__subclasshook__', # '__weakref__', 'name', 'phone'] 

The OP specifically mentions that he is interested in cases where there is no __dict__ — otherwise he could use vars

vars() is close to what I want, but it doesn’t work unless an object has a dict, which isn’t always true (e.g. it’s not true for a list, a dict, etc.). he clearly said that is NOT what he wants

What you probably want is dir() .

The catch is that classes are able to override the special __dir__ method, which causes dir() to return whatever the class wants (though they are encouraged to return an accurate list, this is not enforced). Furthermore, some objects may implement dynamic attributes by overriding __getattr__ , may be RPC proxy objects, or may be instances of C-extension classes. If your object is one these examples, they may not have a __dict__ or be able to provide a comprehensive list of attributes via __dir__ : many of these objects may have so many dynamic attrs it doesn’t won’t actually know what it has until you try to access it.

In the short run, if dir() isn’t sufficient, you could write a function which traverses __dict__ for an object, then __dict__ for all the classes in obj.__class__.__mro__ ; though this will only work for normal python objects. In the long run, you may have to use duck typing + assumptions — if it looks like a duck, cross your fingers, and hope it has .feathers .

Not sure if this is what you’re looking for, but. attrs = dir(obj) will store the array of attributes as strings in attrs . Then to access them, you can always use getattr(obj, attrs[i]) to get the i th attribute in the attrs array.

Источник

Метод getattr() в Python — доступ к атрибутам

Python getattr() — это встроенный метод, который возвращает значение именованного атрибута объекта. Если он не найден, он возвращает значение по умолчанию, предоставленное функции. Функция getattr() возвращает значение указанного атрибута из указанного объекта.

Функция Python getattr()

Что такое getattr() в Python?

Метод getattr() в Python используется для доступа к значению атрибута объекта, а также дает возможность выполнить значение по умолчанию в случае недоступности ключа.

Синтаксис и параметры

  • Параметр object является обязательным, и это объект.
  • attribute — это имя атрибута, из которого вы хотите получить значение.
  • Параметр default является необязательным и возвращает значение, если атрибут не существует.

Функция getattr() с объектом

Давайте возьмем пример, в котором мы создаем объект, а затем получаем доступ к его свойствам с помощью функции getattr().

Итак, мы создали объект с именем duffers, а затем использовали функцию getattr() для получения всех значений атрибутов.

Значение по умолчанию

Давайте добавим значение по умолчанию в функцию getattr().

В приведенном выше коде мы указали значение по умолчанию для свойства catchphrase.

Допустим, мы не предоставляем значение по умолчанию для нового свойства, которого нет в объекте, и видим результат.

Это означает, что у объекта StrangerThings нет ключевой фразы атрибута. Так мы не можем получить его значение, которого даже не существует.

Если мы не предоставляем какое-либо значение по умолчанию, когда ключевая фраза именованного атрибута не найдена, возникает ошибка AttributeError, говорящая, что у объекта нет атрибута ключевой фразы. Итак, используйте параметр default , чтобы написать сообщение, когда атрибут не существует.

Автор статей и разработчик, делюсь знаниями.

Источник

Читайте также:  Php убрать все переносы строк
Оцените статью