1
import requests
response = requests.get('http://httpbin.org/get')
print vars(response) # no response.text listed
print response.text # value printed

Why does vars(response) not list response.text when that value exists?

dir(response) does list response.text, but that does not print the value of it.

wisbucky
  • 33,218
  • 10
  • 150
  • 101
  • @aruisdante the question here is basically about `vars()`, `text` and other properties that a `Response` class has. – alecxe Feb 20 '15 at 19:01

2 Answers2

2

For the first question, the reason text doesn't show up in vars is because it's a property (defined by @property) as opposed to a class attribute (which is what ends up in __dict__ shown by vars).

For the second question, this is because the way dir and vars work.

From the documentation for vars:

vars([object])

Return the dict attribute for a module, class, instance, or any other object with a dict attribute.

Objects such as modules and instances have an updateable dict attribute; however, other objects may have write restrictions on their dict attributes (for example, new-style classes use a dictproxy to prevent direct dictionary updates).

Without an argument, vars() acts like locals(). Note, the locals dictionary is only useful for reads since updates to the locals dictionary are ignored.

And for dir:

The default dir() mechanism behaves differently with different types of objects, as it attempts to produce the most relevant, rather than complete, information:

If the object is a module object, the list contains the names of the module’s attributes. If the object is a type or class object, the list contains the names of its attributes, and recursively of the attributes of its bases. Otherwise, the list contains the object’s attributes’ names, the names of its class’s attributes, and recursively of the attributes of its class’s base classes.

So basically dir just prints out the attributes of the passed in argument, not its corresponding value.

Also, this answer is pretty comprehensive in explaining the differences.

Community
  • 1
  • 1
Sanjay T. Sharma
  • 22,857
  • 4
  • 59
  • 71
  • 1
    Ah, thank you, you explained the key: `text` is a class property as opposed to a class attribute. And looking into the source code, it is because `text` is not just a simple variable, it is a property that does some additional logic. – wisbucky Feb 20 '15 at 19:28
1

It is not in the vars results because vars does not resolve attributes to the parent class of an object. See this other thread on SO.

You can request all "attributes, its class's attributes, and recursively the attributes of its class's base classes" by using dir on the object:

In [1]: import requests

In [2]: response = requests.get('http://httpbin.org/get')

In [3]: 'text' in vars(response)
Out[3]: False

In [4]: 'text' in dir(response)
Out[4]: True
Community
  • 1
  • 1
logc
  • 3,813
  • 1
  • 18
  • 29
  • OK, so that is the technical reason. But why would `response.text` be an attribute whereas `response.status_code` is not an attribute? They seem like they should be in the same category. – wisbucky Feb 20 '15 at 19:18
  • @wisbucky that question is for the designers of requests. What one can gather from the source code [here](https://github.com/kennethreitz/requests/blob/bd3cf95e34aa49c8d764c899672048df107e0d70/requests/models.py#L520) is that `status_code` is an instance variable because it is initialized in the constructor `__init__`, while `text` is a class `@property`. Probably this is because constructing the text requires more logic than just evaluating a value ... – logc Feb 20 '15 at 19:23