0

I am learning to compose professional codes through exploring Django source code.

In django.urls.resolvers | Django documentation | Django, it reads:

class LocaleRegexProvider(object):
    def describe(self):
        description = "'{}'".format(self.regex.pattern)
        if getattr(self, 'name', False):
            description += " [name='{}']".format(self.name)
        return description

I assume that getattr(self, 'name', False): can be substituted by more readable code hasattr(self, 'name')

For exmaple

In [22]: if getattr(str,'split',False):
    ...:     print("Str has 'split' attribute")
    ...: else:
    ...:     print("Str has not 'split' attribute")
    ...:
Str has 'split' attribute
In [25]: if getattr(str,'sp',False):
...:     print("Str has 'sp' attribute")
...: else:
...:     print("Str has not 'sp' attribute")
...:
Str has not 'sp' attribute

As for hasattr

In [23]: if hasattr(str,'split'):
    ...:     print("Str has 'split' attribute")
    ...: else:
    ...:     print("Str has not 'split' attribute")
    ...:
Str has 'split' attribute
In [24]: if hasattr(str,'sp'):
...:     print("Str has 'sp' attribute")
...: else:
...:     print("Str has not 'sp' attribute")
...:
Str has not 'sp' attribute

It seems hasattrshort and readable.

There's a question about their comparison which do not cover this point. Python hasattr vs getattr - Stack Overflow

Is it a better practice to apply getattr() in this context?

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138

1 Answers1

2

hasattr and getattr do different things and are not interchangeable in this case.

Consider the case where the name value is set to be an empty string. hasattr(self, 'name') will return True, while getattr(self, 'name', False) will return that empty string - which is evaluated as False in a boolean context.

To replace the getattr call, you'd need something like if hasattr(self, 'name') and self.name:, which does two attribute lookups rather than one.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83