Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Python Object-Oriented Programming

You're reading from   Python Object-Oriented Programming Learn how and when to apply OOP principles to build scalable and maintainable Python applications

Arrow left icon
Product type Paperback
Published in Nov 2025
Publisher Packt
ISBN-13 9781836642596
Length 542 pages
Edition 5th Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Steven F. Lott Steven F. Lott
Author Profile Icon Steven F. Lott
Steven F. Lott
Dusty Phillips Dusty Phillips
Author Profile Icon Dusty Phillips
Dusty Phillips
Arrow right icon
View More author details
Toc

Table of Contents (17) Chapters Close

Preface 1. Chapter 1 Object-Oriented Design 2. Chapter 2 Objects in Python FREE CHAPTER 3. Chapter 3 When Objects Are Alike 4. Chapter 4 Expecting the Unexpected 5. Chapter 5 When to Use Object-Oriented Programming 6. Chapter 6 Abstract Base Classes and Operator Overloading 7. Chapter 7 Python Type Hints 8. Chapter 8 Python Data Structures 9. Chapter 9 The Intersection of Object-Oriented and Functional Programming 10. Chapter 10 The Iterator Pattern 11. Chapter 11 Common Design Patterns 12. Chapter 12 Advanced Design Patterns 13. Chapter 13 Testing Object-Oriented Programs 14. Chapter 14 Concurrency 15. Other Books You May Enjoy 16. Index

1.4 Specifying attributes and behaviors

We now have a grasp of some basic object-oriented terminology. Objects are instances of classes that can be associated with each other. A specific orange on the table in front of us is said to be an instance of the general class of oranges. As we’ll see in the following sections, the behaviors are implemented as “methods” of the class, introducing another bit of terminology to the mix.

The orange has a state, for example, ripe or raw; we implement the state of an object via the values of specific attributes. An orange also has behaviors. By themselves, oranges are generally passive. State changes are imposed on them. (Consider how alarming an active orange would be.) Let’s dive into the meaning of those two words, state and behaviors.

1.4.1 Data describes object state

Let’s start with data. Data represents the individual characteristics of a certain object; its current state. A class defines the characteristics of all objects that are its members. Any specific object can have different data values for a given characteristic. For example, the three oranges on our table (if we haven’t eaten any) could each weigh a different amount. The orange class could have a weight attribute to represent that datum. All instances of the orange class have a weight attribute, but each orange has a different value for this attribute. Attributes don’t have to be unique, though; any two oranges may weigh the same amount.

Attributes are frequently referred to as members or properties. Some authors suggest that the terms have different meanings, usually that attributes are settable, while properties are read-only. A Python property can be defined as read-only, but the value will be based on attribute values that are — ultimately — writable, making the concept of read-only rather pointless; throughout this book, we’ll see the two terms used interchangeably. In addition, as we’ll discuss in  Chapter 5, the property keyword has a special meaning in Python for a particular kind of attribute.

In Python, we can also call an attribute an instance variable. This can help clarify the way attributes work. They are variables with unique values for each instance of a class. Python has other kinds of attributes, but we’ll focus on the most common kind to get started.

In our fruit inventory application, the fruit farmer may want to know what orchard the orange came from, when it was picked, and how much it weighs. They might also want to keep track of where each Basket is stored. Apples might have a color attribute, and barrels might come in different sizes.

We’ll often notice that multiple classes have the same properties; we may want to know when apples are picked, too. For this first example, we’ll add a few different attributes to our class diagram.  Figure 1.3 shows some attributes:

PIC
Figure 1.3: Class diagram with attributes

Depending on how detailed our design needs to be, we can also specify the type for each attribute’s value. In UML, attribute types are often generic names common to many programming languages, such as integer, floating-point number, string, byte, or Boolean. However, they can also represent generic collections such as lists, trees, or graphs, or most notably, other, non-generic, application-specific classes. This is one area where the design stage can overlap with the programming stage. The various primitives and built-in collections available in one programming language may be different from what is available in another.

 Figure 1.4 shows some attributes with (mostly) Python-specific type hints:

PIC
Figure 1.4: Class diagram with attributes and their types

Usually, we don’t need to be overly concerned with data types at the design stage, as implementation-specific details are chosen during the programming stage. Generic names are normally sufficient for design; that’s why we included date as a placeholder for a Python type such as datetime.datetime. If our design calls for a list container type, Java programmers can choose to use a LinkedList or an ArrayList when implementing it, while Python programmers (that’s us!) might specify list[Apple] as a type hint, and use the list type for the implementation.

In our fruit-farming example so far, our attributes are all built-in primitive types. However, there are some implicit attributes that we can make explicit; these implement the associations. For a given orange, we have an attribute referring to the basket that holds that orange, the basket attribute, with a type hint of Basket.

1.4.2 Behaviors are actions

Now that we know how data defines the object’s state, the last undefined term we need to look at is behavior. Behaviors are actions that can occur on an object. The behaviors that can be performed on members of a class are expressed as the methods of a class. At the programming level, methods are essentially functions with access to an object’s attributes — in Python, these are the instance variables of an object. Like functions, methods can also accept parameters and return values.

A method’s parameters define objects that need to be passed into that method. The actual object instances that are passed into a method during a specific invocation are referred to as the argument values. These objects are bound to parameter variable names in the method body. They are used by the method to perform whatever behavior or task it is meant to do. Returned values are the results of that task. Internal state changes are a possible side-effect of evaluating a method. (Some folks like to talk about “calling” a method or “executing” a method; these are all synonyms.)

We’ve stretched our comparing apples and oranges example into a basic (if far-fetched) inventory application. Let’s stretch it a little further and see whether it breaks. The idea is to capture enough details of the problem domain; the software we need to write may not implement every detail of the initial model. One action that can be associated with oranges is the conceptual pick action. As we think about implementation details for this class, a pick method might need to do two things:

  • Place the orange in a basket by updating the Basket attribute of the orange.

  • Add the orange to the Orange list on the given Basket.

So, this pick method may need to know what basket it is dealing with. We do this by giving the method a Basket parameter. Since our fruit farmer also sells juice, we can add a squeeze method to the Orange class. When evaluated, the squeeze method might return the amount of juice retrieved, while also removing the Orange from the Basket it was in.

The class Basket can have a sell action. When a basket is sold, our inventory system might update some data on as-yet-unspecified objects for accounting and profit calculations. Alternatively, our basket of oranges might go bad before we can sell them, so we may also need to add a discard method.

 Figure 1.5 adds methods to our diagram:

PIC
Figure 1.5: Class diagram with attributes and methods

Do we really need all of these methods and the related associations? Unsurprisingly, the answer is often “no”: the application software doesn’t need to model all of these behaviors. For now, we want to throw ideas at the model to explore what’s possible. Later, we’ll prune this back to what’s necessary.

Adding attributes and methods to individual objects allows us to create a system of interacting objects. Each object in the system is a member of a certain class. These classes specify what types of data the object can hold and what methods can be invoked on it. The data in each object can be in a different state from other instances of the same class; each object may react to method calls differently because of the differences in state.

Object-oriented analysis and design are all about figuring out what those objects are and how they should interact. Each class has responsibilities and collaborations. The next section describes principles that can be used to make those interactions as intuitive as possible.

Note that selling a basket is not unconditionally a feature of the Basket class. It may be that some other class (not shown) cares about the various baskets and where they are. We often have boundaries around our design. We will also have questions about responsibilities allocated to various classes. The responsibility allocation problem doesn’t always have a tidy technical solution, forcing us to draw (and redraw) our UML diagrams more than once to examine alternative designs.

In many contexts, the analysis process can also be enlightening for product owners and users. What may seem — at first — like an insurmountable business problem, requiring lots of expensive software, may turn out to be a failure of two organizations to collaborate. The process of creating an object-oriented analytical model may reveal details that aren’t really solvable with more software. It’s not unusual for a software project to proceed through a great deal of object-oriented model building, and then end with a successful outcome for the ultimate users, but little or no software being written. The models (and the resulting insight) were adequate to understand what’s really going on.

lock icon The rest of the chapter is locked
CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Python Object-Oriented Programming
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Modal Close icon
Modal Close icon