54

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?

max
  • 49,282
  • 56
  • 208
  • 355

4 Answers4

44

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.

Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
20

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)

Tim
  • 41,901
  • 18
  • 127
  • 145
James Polley
  • 7,977
  • 2
  • 29
  • 33
12

No, that's fine. Since an object reference is required there is no way to have them shadow the built-in.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 1
    So I can use any valid identifier as an attribute name, except one starting with `__`, or one that's identical to a keyword? – max Feb 02 '12 at 08:50
  • you can use any including __something or a keyword. Well, some with __ have special meaning. – Johan Lundberg Feb 02 '12 at 08:51
  • You can start them with `__` so long as they also *end* with `__`. Do note that Python uses many of those for its own purposes though (such as `__dict__`, `__init__`, and `__new__`). – Ignacio Vazquez-Abrams Feb 02 '12 at 08:52
  • Is the rule that if they also end with __ they are not mangled? – Johan Lundberg Feb 02 '12 at 08:54
  • @IgnacioVazquez-Abrams: oh that's precisely why I thought I shouldn't use them (who knows which are used for the language's "own purposes"). And why if I did risk using them, must I end them with `__`? – max Feb 02 '12 at 08:54
  • 1
    @max: [Python Language Reference, section 3, "Data model"](http://docs.python.org/reference/datamodel.html) – Ignacio Vazquez-Abrams Feb 02 '12 at 08:56
  • 6
    You shouldn't start them with `__` at all. `__foo` get's mangled, which isn't a problem if it's a private property. `__foo__` signifies that it's Python internals. There is no *problem* with doing so, but it is bad form. – Lennart Regebro Feb 02 '12 at 14:08
  • 2
    depends on what you mean by "fine". Will the code still run? Sure. Is using built-in names a bad practice and can lead to confusion? Yes, and that should be enough of a reason for anyone to avoid using built-in types/functions as variable names. – icdevppl Aug 28 '17 at 19:42
  • 1
    @icdevppl: Even as an attribute name, as the question asks? – Ignacio Vazquez-Abrams Aug 28 '17 at 19:44
0

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

Adam Hughes
  • 14,601
  • 12
  • 83
  • 122