Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to differentiate between hasattr and normal attribute access in __getattr__?

Tags:

python

class a_class:
    def __getattr__(self, name):
        # if called by hasattr(a, 'b') not by a.b
        # print("I am called by hasattr")
        print(name)

a = a_class()
a.b_attr

hasattr(a, 'c_attr')

Please take a look the comment inside __getattr__. How do I do that? I am using Python 3. The reason is I want to create attribute dynamically but I don't want to do that when using hasattr. Thanks.

like image 730
arjunaskykok Avatar asked Sep 14 '13 03:09

arjunaskykok


People also ask

What is the difference between Getattribute and Getattr?

__getattribute__ has a default implementation, but __getattr__ does not. This has a clear meaning: since __getattribute__ has a default implementation, while __getattr__ not, clearly python encourages users to implement __getattr__ .

Does Hasattr call Getattr?

hasattr() checks for the existence of an attribute by trying to retrieve it. This is implemented by calling getattr(object, name) , which does a lookup, and seeing whether an exception is raised.

What is __ Getattr __?

__getattr__(self, name) Is an object method that is called if the object's properties are not found. This method should return the property value or throw AttributeError . Note that if the object property can be found through the normal mechanism, it will not be called.

What is Hasattr in Python?

Python hasattr() Function The hasattr() function returns True if the specified object has the specified attribute, otherwise False .


1 Answers

You can't, without cheating. As the documentation says:

This [that is, hasattr] is implemented by calling getattr(object, name) and seeing whether it raises an exception or not.

In other words, you can't block hasattr without also blocking getattr, which basically means you can't block hasattr at all if you care about accessing attributes.

By "cheating" I mean one of these solutions that clever people like to post on here that involve an end-run around essentially all of Python. They typically involve reassigning builtins, inspecting/manipulating the call stack, using introspection to peek at the literal source code, modifying "secret" internal attributes of objects, and so on. For instance, you could look at the call stack to see if hasattr is in the call chain. This type of solution is possible, but extremely fragile, with possibility of breaking in future Python versions, on non-CPython implementations, or in situations where another equally ugly and devious hack is also being used.

You can see a similar question and some discussion here.

like image 174
BrenBarn Avatar answered Sep 21 '22 08:09

BrenBarn