Which is the convention according to PEP 8 for writing variables that identify class names (not instances)?

That is, given two classes, A and B, which of the following statements would be the right one?

target_class = A if some_condition else B
instance = target_class()

or

TargetClass = A if some_condition else B
instance = TargetClass()


As stated in the style guide,

Class Names:

Class names should normally use the CapWords convention.

But also

Method Names and Instance Variables:

Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.

In my opinion, these two conventions clash and I can’t find which one prevails.

In lack of a specific covering of this case in PEP 8, one can make up an argument for both sides of the medal:

One side is: As A and B both are variables as well, but hold a reference to a class, use CamelCase (TargetClass) in this case.

Nothing prevents you from doing

class A: pass
class B: pass
x = A
A = B
B = x

Now A and B point to the respectively other class, so they aren’t really fixed to the class.

So A and B have the only responsibility to hold a class (no matter if they have the same name or a different one), and so has TargetClass.


In order to remain unbiased, we as well can argue in the other way: A and B are special in so far as they are created along with their classes, and the classes’ internals have the same name. In so far they are kind of “original”, any other assignment should be marked special in so far as they are to be seen as a variable and thus in lower_case.


The truth lies, as so often, somewhere in the middle. There are cases where I would go one way, and others where I would go the other way.

Example 1: You pass a class, which maybe should be instantiated, to a method or function:

def create_new_one(cls):
    return cls()

class A: pass
class B: pass

print(create_new_one(A))

In this case, cls is clearly of very temporary state and clearly a variable; can be different at every call. So it should be lower_case.

Example 2: Aliasing of a class

class OldAPI: pass
class NewAPI: pass
class ThirdAPI: pass
CurrentAPI = ThirdAPI

In this case, CurrentAPI is to be seen as a kind of alias for the other one and remains constant throughout the program run. Here I would prefer CamelCase.

In case of doubt I would do the same as Python developers. They wrote the PEP-8 after all.

You can consider your line:

target_class = A if some_condition else B

as an in-line form of the pattern:

target_class = target_class_factory()

and there is a well-known example for it in the Python library, the namedtuple, which uses CamelCase.

I personally think that whether the variable you mentioned, which holds a reference to a class, is defined as a temporary variable (for example in a procedure or function) or as a derivation from an existing class in the global spectrum has the most weight in the case of which one to use. So to summarise from the reply above:

  • If the variable is temporary, e.g. inside a function or used in a single instance in the solving of a problem, it should be lower_case with underscore separation.

  • If the variable is within the global spectrum, and is defined along with the other classes as an alias or derivation to use to create objects in the body of the program, it should be defined using CamelCase.

I finally found some light in the style guide:

Class Names

[…]

The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.

may be used is not a strong statement, but it covers the case, as the variable was intended to be used as a callable.

So, for general purpose I think that

target_class = A if some_condition else B
instance = target_class()

is better than

TargetClass = A if some_condition else B
instance = TargetClass()