Clean Code in Python
eBook - ePub

Clean Code in Python

Develop maintainable and efficient code, 2nd Edition

Mariano Anaya

Partager le livre
  1. 422 pages
  2. English
  3. ePUB (adapté aux mobiles)
  4. Disponible sur iOS et Android
eBook - ePub

Clean Code in Python

Develop maintainable and efficient code, 2nd Edition

Mariano Anaya

DĂ©tails du livre
Aperçu du livre
Table des matiĂšres
Citations

À propos de ce livre

Tackle inefficiencies and errors the Pythonic wayKey Features‱ Enhance your coding skills using the new features introduced in Python 3.9‱ Implement the refactoring techniques and SOLID principles in Python‱ Apply microservices to your legacy systems by implementing practical techniquesBook DescriptionExperienced professionals in every field face several instances of disorganization, poor readability, and testability due to unstructured code. With updated code and revised content aligned to the new features of Python 3.9, this second edition of Clean Code in Python will provide you with all the tools you need to overcome these obstacles and manage your projects successfully. The book begins by describing the basic elements of writing clean code and how it plays a key role in Python programming. You will learn about writing efficient and readable code using the Python standard library and best practices for software design. The book discusses object-oriented programming in Python and shows you how to use objects with descriptors and generators. It will also show you the design principles of software testing and how to resolve problems by implementing software design patterns in your code. In the concluding chapter, we break down a monolithic application into a microservices-based one starting from the code as the basis for a solid platform. By the end of this clean code book, you will be proficient in applying industry-approved coding practices to design clean, sustainable, and readable real-world Python code.What you will learn‱ Set up a productive development environment by leveraging automatic tools‱ Leverage the magic methods in Python to write better code, abstracting complexity away and encapsulating details‱ Create advanced object-oriented designs using unique features of Python, such as descriptors‱ Eliminate duplicated code by creating powerful abstractions using software engineering principles of object-oriented design‱ Create Python-specific solutions using decorators and descriptors‱ Refactor code effectively with the help of unit tests‱ Build the foundations for solid architecture with a clean code base as its cornerstoneWho this book is forThis book is designed to benefit new as well as experienced programmers. It will appeal to team leads, software architects and senior software engineers who would like to write Pythonic code to save on costs and improve efficiency. The book assumes that you have a strong understanding of programming

Foire aux questions

Comment puis-je résilier mon abonnement ?
Il vous suffit de vous rendre dans la section compte dans paramĂštres et de cliquer sur « RĂ©silier l’abonnement ». C’est aussi simple que cela ! Une fois que vous aurez rĂ©siliĂ© votre abonnement, il restera actif pour le reste de la pĂ©riode pour laquelle vous avez payĂ©. DĂ©couvrez-en plus ici.
Puis-je / comment puis-je télécharger des livres ?
Pour le moment, tous nos livres en format ePub adaptĂ©s aux mobiles peuvent ĂȘtre tĂ©lĂ©chargĂ©s via l’application. La plupart de nos PDF sont Ă©galement disponibles en tĂ©lĂ©chargement et les autres seront tĂ©lĂ©chargeables trĂšs prochainement. DĂ©couvrez-en plus ici.
Quelle est la différence entre les formules tarifaires ?
Les deux abonnements vous donnent un accĂšs complet Ă  la bibliothĂšque et Ă  toutes les fonctionnalitĂ©s de Perlego. Les seules diffĂ©rences sont les tarifs ainsi que la pĂ©riode d’abonnement : avec l’abonnement annuel, vous Ă©conomiserez environ 30 % par rapport Ă  12 mois d’abonnement mensuel.
Qu’est-ce que Perlego ?
Nous sommes un service d’abonnement Ă  des ouvrages universitaires en ligne, oĂč vous pouvez accĂ©der Ă  toute une bibliothĂšque pour un prix infĂ©rieur Ă  celui d’un seul livre par mois. Avec plus d’un million de livres sur plus de 1 000 sujets, nous avons ce qu’il vous faut ! DĂ©couvrez-en plus ici.
Prenez-vous en charge la synthÚse vocale ?
Recherchez le symbole Écouter sur votre prochain livre pour voir si vous pouvez l’écouter. L’outil Écouter lit le texte Ă  haute voix pour vous, en surlignant le passage qui est en cours de lecture. Vous pouvez le mettre sur pause, l’accĂ©lĂ©rer ou le ralentir. DĂ©couvrez-en plus ici.
Est-ce que Clean Code in Python est un PDF/ePUB en ligne ?
Oui, vous pouvez accĂ©der Ă  Clean Code in Python par Mariano Anaya en format PDF et/ou ePUB ainsi qu’à d’autres livres populaires dans Computer Science et Programming in Python. Nous disposons de plus d’un million d’ouvrages Ă  dĂ©couvrir dans notre catalogue.

Informations

Année
2021
ISBN
9781800562097

6

Getting More Out of Our Objects with Descriptors

This chapter introduces a new concept that is more advanced in Python development since it features descriptors. Moreover, descriptors are not something programmers of other languages are familiar with, so there are no easy analogies or parallelisms to make.
Descriptors are another distinctive feature of Python that take object-oriented programming to another level, and their potential allows users to build more powerful and reusable abstractions. Most of the time, the full potential of descriptors is observed in libraries or frameworks.
In this chapter, we will achieve the following goals that relate to descriptors:
  • Understand what descriptors are, how they work, and how to implement them effectively
  • Analyze the two types of descriptors (data and non-data descriptors) in terms of their conceptual differences and implementation details
  • Reuse code effectively through descriptors
  • Analyze examples of good uses of descriptors, and how to take advantage of them for our API libraries

A first look at descriptors

First, we will explore the main idea behind descriptors to understand their mechanics and internal workings. Once this is clear, it will be easier to assimilate how the different types of descriptors work, which we will explore in the next section.
Once we have a general understanding of the idea behind descriptors, we will look at an example where their use gives us a cleaner and more Pythonic implementation.

The machinery behind descriptors

The way descriptors work is not all that complicated, but the problem with them is that there are a lot of caveats to take into consideration, so the implementation details are of the utmost importance here.
To implement descriptors, we need at least two classes. For this generic example, the client class will take advantage of the functionality we want to implement in the descriptor (this is generally just a domain model class, a regular abstraction we create for our solution), and the descriptor class will implement the logic of the descriptor itself.
A descriptor is, therefore, just an object that is an instance of a class that implements the descriptor protocol. This means that the interface of this class must contain at least one of the following magic methods (part of the descriptor protocol as of Python 3.6+):
  • __get__
  • __set__
  • __delete__
  • __set_name__
For the purposes of this initial high-level introduction, the following naming conventions will be used:
Name
Meaning
ClientClass
The domain-level abstraction that will take advantage of the functionality to be implemented by the descriptor. This class is said to be a client of the descriptor.
This class contains a class attribute (named descriptor by this convention), which is an instance of DescriptorClass.
DescriptorClass
The class that implements the descriptor itself. This class should implement some of the aforementioned magic methods that entail the descriptor protocol.
client
An instance of ClientClass.
client = ClientClass().
descriptor
An instance of DescriptorClass.
descriptor = DescriptorClass().
This object is a class attribute that is placed in ClientClass.
Table 6.1: Descriptor naming conventions used in this chapter
This relationship is illustrated in Figure 6.1:
Picture 1
Figure 6.1: The relationship between ClientClass and DescriptorClass
A very important observation to keep in mind is that for this protocol to work, the descriptor object has to be defined as a class attribute. Creating this object as an instance attribute will not work, so it must be in the body of the class, and not in the __init__ method.
Always place the descriptor object as a class attribute!
On a slightly more critical note, readers can also note that it is possible to implement the descriptor protocol partially—not all methods must always be defined; instead, we can implement only those we need, as we will see shortly.
So, now we have the structure in place—we know what elements are set and how they interact. We need a class for the descriptor, another class that will consume the logic of the descriptor, which, in turn, will have a descriptor object (an instance of DescriptorClass) as a class attribute, and instances of ClientClass that will follow the descriptor protocol when we call for the attribute named descriptor. But now what? How does all of this fit into place at runtime?
Normally, when we have a regular class and we access its attributes, we simply obtain the objects as we expect them, and even their properties, as in the following example:
>>> class Attribute: ... value = 42 ... >>> class Client: ... attribute = Attribute() ... >>> Client().attribute <__main__.Attribute object at 0x...> >>> Client().attribute.value 42 
But, in the case of descriptors, something different happens. When an object is defined as a class attribute (and this one is a descriptor), when a client requests this attribute, instead of getting the object itself (as we would expect from the previous example), we get the result of having called the __get__ magic method.
Let's start with some simple code that only logs information about the context, and returns the same client object:
class DescriptorClass: def __get__(self, instance, owner): if instance is None: return self logger.info( "Call: %s.__get__(%r, %r)", self.__class__.__name__, instance, owner ) return instance class ClientClass: descriptor = Descriptor...

Table des matiĂšres