In the section Method Names and Instance Variables, the Python Style Guide (aka PEP 0008) says, "Use one leading underscore only for non-public methods and instance variables." Why then, does the _replace method on namedtuple have a leading underscore? namedtuple classes themselves do not invoke _replace at all, and meanwhile the existence of _replace is advertised in the docstring for namedtuple() (see here, for example).


namedtuple is a bit unusual thing in python. It is not a base class, it is a class generator. Invoking it creates a new class that uses a tuple for its storage and can be manipulated as either tuple or normal class with named fields.

The generated class is intended to be used as a base for your own types that will add methods, and constraints. Including constraints that tie the values of individual fields together.

So the namedtuple might be used as base for classes that don't support replacing. And since derived class can't remove methods its base provides, the method must not be public.

However some derived classes might want that functionality. So it is provided, as internal method. The subclass can export it if it has a good use for it.


In the namedtuple documentation, it says:

Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, and underscores but do not start with a digit or underscore and cannot be a keyword such as class, for, return, global, pass, print, or raise.

Because namedtuples have a dynamic field structure. You give a list of identifiers and it creates a class with related fields.

Since it have a dynamic field type, developers tries to avoid as much condition as possible to make field_names flexible. They named base class methods with an underscore, (_make(), _replace(), _asdict() and _fields) so you can use un-underscored names for field names or like.

No identifier can start with a digit and no class method or property or field may have the name of a keyword in python as a general rule. As for the last rule of namedtuple field_name naming, names that start with an underscore are not available since they are reserved for method and property names of the namedtuple class.


This was apparently done so that the namedtuple members (_replace, _fields, _field_defaults, _make, and _asdict) would not collide with field names (keys, sort of) that users of namedtuple might wish to create. It seems it is an unfortunate side effect that this collides with the PEP that you provided. (I got here searching for answers after PyCharm's PEP enforcement flagged my use of _fields as "access to a protected member." Irritating, but not a serious issue for me.)

From the documentation at https://docs.python.org/3/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields:

In addition to the methods inherited from tuples, named tuples support three additional methods and two attributes. To prevent conflicts with field names, the method and attribute names start with an underscore.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.