Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: PEP 8 class name as variable

Tags:

python

pep8

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.

like image 763
LostMyGlasses Avatar asked Jul 18 '16 09:07

LostMyGlasses


People also ask

Which choice is PEP 8 compliant as the name of a class?

I try to adhere to the style guide for Python code (also known as PEP 8). Accordingly, the preferred way to name a class is using CamelCase: Almost without exception, class names use the CapWords convention.

What is the use of PEP8 in Python?

PEP 8 is, as python.org puts it, a style guide for Python code. It helps us write code which is easily readable, so that if we were to show to other developers, or even ourselves in the future, they would be able to understand what's going on from the first glimpse.

What are naming conventions in PEP 8?

Naming conventions in PEP 8 Naming conventions are rules, which although not mandatory allow us to keep our code clean and Pythonic. Naming convetnions should be used when naming variables, functions and classes. We've already briefly discussed naming conventions in Python in on of our first tutorials about variables.

What is the best way to name variables in Pep 484?

Names of type variables introduced in PEP 484 should normally use CapWords preferring short names: T, AnyStr, Num. It is recommended to add suffixes _co or _contra to the variables used to declare covariant or contravariant behavior correspondingly:

How many characters can be in a file in PEP8?

PEP 8 suggests lines should be limited to 79 characters. This is because it allows you to have multiple files open next to one another, while also avoiding line wrapping.


4 Answers

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.

like image 198
glglgl Avatar answered Oct 16 '22 22:10

glglgl


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.

like image 42
Almonso Avatar answered Oct 16 '22 23:10

Almonso


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.

like image 38
VPfB Avatar answered Oct 16 '22 23:10

VPfB


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()
like image 37
LostMyGlasses Avatar answered Oct 16 '22 22:10

LostMyGlasses