Hướng dẫn python getattr child class

I have a class who's fields are an instance of another class.

class Field:
    def get(self):
    def set(self, value):
    def delete(self):

class Document:
    def __init__(self):
        self.y = Field()
        self.z = True

What I'd like to be able to do is when an instance of the parent refers to its attributes, instead it calls the child's methods.

d = Document()
d.y = 'some value'  # Calls the `set` function of the Field
d.y == 'some value'  # Calls the `get` function of the Field
del d.y  # Calls the `delete` function of the Field

The other catch is that I only want this behavior when the field is of type Field.

I'm running into recursion problems try to use __getattr__ and the like, along the lines of:

def __getattr__(self, key):
    if isinstance(getattr(self, key), Field):
        return getattr(self, key).get()
    return getattr(self, key)

The recursion is fairly obvious why its happening... but how do I avoid it?

I've seen a few examples already on StackOverflow, but I can't seem to figure out how to get around it.

  • Maximum recursion depth error with getattr
  • Understanding the difference between __getattr__ and __getattribute__

Python getattr() function is used to access the attribute value of an object and also gives an option of executing the default value in case of unavailability of the key.

Syntax : getattr(obj, key, def)

Parameters : 

  • obj : The object whose attributes need to be processed.
  • key : The attribute of object
  • def : The default value that need to be printed in case attribute is not found.

Returns : Object value if value is available, default value in case attribute is not present 
and returns AttributeError in case attribute is not present and default value is not 
specified. 

How getattr() works in Python

Example 1: Demonstrating working of getattr() 

Python3

class GfG:

    name = "GeeksforGeeks"

    age = 24

obj = GfG()

print("The name is " + getattr(obj, 'name'))

print("Description is " + getattr(obj,

                                  'description',

                                  'CS Portal'))

print("Motto is " + getattr(obj, 'motto'))

Output: 

The name is GeeksforGeeks
Description is CS Portal

Exception: 

AttributeError: GfG instance has no attribute 'motto'

Example 2: getattr() when named attribute is not found

Python3

class GfG:

    name = "GeeksforGeeks"

    age = 24

obj = GfG()

print("Gender is " + getattr(obj, 'gender'))

Output:

AttributeError: 'GfG' object has no attribute 'gender'

 Example 3: Performance Analysis and getattr python with parameter

Python3

import time

class GfG:

    name = "GeeksforGeeks"

    age = 24

obj = GfG()

start_getattr = time.time()

print("The name is " + getattr(obj, 'name'))

print("Time to execute getattr " + str(time.time() - start_getattr))

start_obj = time.time()

print("The name is " + obj.name)

print("Time to execute conventional method " + str(time.time() - start_obj))

Output: 

The name is GeeksforGeeks
Time to execute getattr 5.0067901611328125e-06
The name is GeeksforGeeks
Time to execute conventional method 1.1920928955078125e-06

Example 4:  getattr Python default value

Python3

class GfG:

    name = "GeeksforGeeks"

    age = 24

obj = GfG()

print("Motto is " + getattr(obj, 'motto'))

Output:

AttributeError: 'GfG' object has no attribute 'motto'

Example 5: Python getattr() function call

Python3

class GfG:

    def __init__(self, name, age):

        self.name = name

        self.age = age

    def call(self, x):

        print(f"{self.name} called with parameters '{x}'")

        return

obj = GfG("Vivek", 10)

print(obj)

print(GfG)

print(getattr(obj,'call'))

getattr(obj,'call')('arg')

Output:

<__main__.GfG object at 0x0000023C1ED92748>

>
Vivek called with parameters 'arg'

Result : Conventional method takes less time than getattr(), but when default values have to be used in case of missing attributes, getattr() is a good choice.

Applications: The are many applications of getattr(), a few of them already mentioned in cases of absence of attributes of objects, in web developments where some of the form attributes are optional. Also useful in cases of Machine Learning feature collections in case some features sometimes go missing in data collection.