Question :
I know to never use built-in function names as variable identifiers.
But are there any reasons not to use them as attribute or method identifiers?
For example, is it safe to write my_object.id = 5
, or define an instance method dict
in my own class?
Answer #1:
It won’t confuse the interpreter but it may confuse people reading your code. Unnecessary use of builtin names for attributes and methods should be avoided.
Another ill-effect is that shadowing builtins confuses syntax highlighters in most python-aware editors (vi, emacs, pydev, idle, etc.) Also, some of the lint tools will warn about this practice.
Answer #2:
Yes it’s bad practice. It might not immediately break anything for you, but it still hurts readability of the code.
To selectively quote from PEP20:
Beautiful is better than ugly.
Simple is better than complex.
Readability counts.
If the implementation is hard to explain, it’s a bad idea.
Seeing a call to myobject.dict()
it would be natural to assume that it’s going to return myobject.__dict__
, or that myobject.id()
returns the same thing as id(myobject)
It’s possible for them to find out that they’re wrong; but that will take time and effort and probably lead to some mistakes while they figure it out. Calling your attribute myobject.object_id_number
is much longer, but makes it clearer that it’s different to id(myobject)
Answer #3:
No, that’s fine. Since an object reference is required there is no way to have them shadow the built-in.
Answer #4:
I go back and forth on functions a lot when the input variables mimic python builtins. For example, the word bytes
is a python builtin, but consider a utility library that parses bytes:
def parse_bytes(bytes):
pass
I’d argue this has great readability, but pep8 linters don’t like it. Instead I could do
def parse_bytes(bytearray):
pass
def parse_bytes(somebytes):
pass
Or use type hinting
def parse_bytes(b: bytes):
pass
But all of these seem worse. Same thing happens if your variable name is input
…
At the end of the day I usually go with somebytes