Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content
Python Land
  • Python Tutorial
  • Shop
  • Blog
  • Login / Register
  • Contact
0
Home » Tips & Tricks » Python Attrs: Advanced Data Classes, With Example Code
Python attrs

Python Attrs: Advanced Data Classes, With Example Code

April 9, 2022

The package Python Attrs allows you to create advanced data classes using simple annotations. Of course, python has its own native data class module as well, but the Python attrs package offers a couple of extra features you might like!

Table of Contents

  • 1 Install attrs
  • 2 Attrs vs data classes
  • 3 A basic Python attrs example
  • 4 Python attrs validator example
  • 5 Python attrs converter example
  • 6 Using slots with Python attrs
  • 7 Keep learning

Install attrs

The attrs package is not part of the base library, so you will need to install it with the pip install command or something similar, like Pipenv. You probably also want to create a virtual environment, so it won’t interfere with other projects you have. The package is called attrs, so installing it will look like this:

$ pip install attrs

# or with pipenv:
$ pipenv install attrs

Attrs vs data classes

The authors of attrs have, in fact, worked on the PEP that introduced data classes into Python. Python’s native data classes are intentionally kept simpler and easier to understand while attrs offering the full range of features you might want!

Some of the reasons to choose Python attrs over the built-in data classes are:

  • You are using a Python version from before 3.7. Attrs has you covered since it supports all mainstream Python versions, including CPython 2.7 and PyPy.
  • You want more features: attrs offers validators and converters
  • You want optimal performance and minimal memory usage using attrs slotted classes

A basic Python attrs example

Let’s look at a very basic example first:

import attr

@attr.s
class Person(object):
    name = attr.ib(default='John')
    surname = attr.ib(default='Doe')
    age = attr.ib(init=False)
    
p = Person()
print(p)
p = Person('Bill', 'Gates')
p.age = 60
print(p)

# Output: 
#   Person(name='John', surname='Doe', age=NOTHING)
#   Person(name='Bill', surname='Gates', age=60)

A couple of observations:

  • The syntax is less elegant and more verbose than that of data classes, but you get extra features in return.
  • Similar to data classes, you get a nicely formatted representation of your data when you print it.
  • The attrs package uses smartly picked names like attr.ib, so you only need to import attr. You can, alternatively, import the full names. For example with from attr import attrib, attrs, and use those names instead. The functionality is the same.

Next let’s look at the most important features this package offers over regular data classes: validators and converters.

Python attrs validator example

You can add validators to your attrs data class in two ways:

  1. Using a decorator
  2. By providing a callable function

I’ll demonstrate the callable function method here first. Attrs offers several validators out of the box, of which we’ll use the instance_of validator in the following example:

>>> @attr.s
... class C(object):
...     x = attr.ib(validator=attr.validators.instance_of(int))
>>> C(42)
C(x=42)
>>> C("a string")

Traceback (most recent call last):
   ...
TypeError: ("'x' must be <type 'int'> (got 'a string' that is a <type 'str'>).", ...

Since we tried to create an object C with a string value for x, the instance_of validator throws an error because it requires an int type instead of a string.

Let’s now define our own validator:

import attr

@attr.s
class DividableByTwo(object):
    x = attr.ib()

    @x.validator
    def check(self, attribute, value):
        if value % 2 != 0:
            raise ValueError(f'{value} is not dividable by 2')

print (DividableByTwo(60))
print (DividableByTwo(11))

# Output will be something like:
# DividableByTwo(x=60)
# ...
# ValueError: 11 is not dividable by 2

Python attrs converter example

A converter takes the value that is set and converts it automatically. You can use this for all kinds of purposes. One example is to automatically convert a value to an int. Again, let’s start with using a callable function, in this case, we simply use Python’s int() function:

import attr

@attr.s
class C(object):
    x = attr.ib(converter=int)

c = C("1")
print(c)
# Output:
# C(x=1)

Our input (the string “1”) was converted to an integer automatically. Because converters are run before validators, you can validate the final value after conversion. E.g., you could combine the above two examples to first convert any input to int, and then check if the value is dividable by two.

Using slots with Python attrs

Finally, you can tell attrs to use slotted classes. Slotted classes have some advantages over regular classes:

  • They have a small memory footprint
  • They are faster

In short, with a slotted class you explicitly state which instance attributes you expect your object instances to have. This way, Python can leave out some checks and such, resulting in less memory usage and slight speed increases. You can find more details in the attrs documentation here.

However, slotted classes come with caveats too, especially when you manually create them. Luckily, attrs offers us a simple way to enable the feature:

import attr

@attr.s(slots=True)
class YourClassName:
    ...

Keep learning

  • Our article on Python data classes
  • Our tutorial on Python classes and objects
  • For more examples, check out the attrs examples page

Get certified with our courses

Learn Python properly through small, easy-to-digest lessons, progress tracking, quizzes to test your knowledge, and practice sessions. Each course will earn you a downloadable course certificate.

  • Sale Product on sale
    The Python Course for Beginners
    Beginners Python Course (2024)
    £ 59.00 Original price was: £ 59.00.£ 39.00Current price is: £ 39.00.
  • Sale Product on sale
    Computer Fundamentals
    Files, Folders, And The Command Line (2024)
    £ 39.00 Original price was: £ 39.00.£ 19.00Current price is: £ 19.00.
  • Sale Product on sale
    Modules, Packages, And Virtual Environments (2024)
    Modules, Packages, And Virtual Environments (2024)
    £ 59.00 Original price was: £ 59.00.£ 39.00Current price is: £ 39.00.

Leave a Comment Cancel reply

You must be logged in to post a comment.

Subscribe to my newsletter for Python news, tips, and tricks!

Footer subscribe

  • Home
  • Python Courses
  • Privacy Policy
  • About Us
  • Contact us
©2025 Python Land - All rights reserved
Python Land is not affiliated with Python.org or the Python Software Foundation
  • Free Tutorial
    • Install Python
      • Online Python Interpreter
      • How To Open Python on Windows, Mac, Linux
    • Introduction to Python
      • The Python REPL
      • Python Variable
      • Python String
      • Python Print function
      • Python Booleans
      • For-loop and While-loop
      • Python Functions
      • Your First Python Program
      • Python Comments
    • Creating Python Programs
      • The Best Python IDE
      • Installing VSCode
      • VSCode Python Extensions
      • VSCode GUI Tour
      • Python in VSCode: Running and Debugging
    • Classes and Objects in Python
      • Python Constructor
      • Python Inheritance
    • Structure Your Project
      • Python Modules And Importing
      • Python Packages
    • Python Data Types
      • Python Integer
      • Python Float
      • Python Tuple
      • Python List
      • Python Set
      • Python Dictionary
    • Language Deep Dives
      • Python Try Except (Exceptions)
      • Python Functions: Advanced Concepts
      • List Comprehension
      • Python Iterator
      • Python Range
      • Python Docstrings
      • Python pass (Do Nothing)
    • Interaction with the OS
      • Python Read And Write File
      • Python Subprocess: Run External Commands
    • Venvs / Package Management
      • Working With Python’s venv
      • Pip install: the Python package manager
      • Python Poetry: Package and venv Management Made Easy
      • Python Pipenv: Another Package Manager
      • Pipx: Safely Install Packages Globally
    • Python Concurrency
      • The Python GIL (Global Interpreter Lock)
      • Setting the Baseline
      • Python Threading
      • Python Multiprocessing
    • Data Processing with Python
      • Working With JSON
        • JMESPath Python: JSON Query Language
      • Python YAML: How to Load, Read, and Write YAML
      • Python CSV: Read And Write CSV Files
    • Migrating From Python 2 to 3
      • Check Python Version On The Command-Line
      • How to Migrate To Python 3
      • Python 3 Advantages
    • Using The Unix Shell
      • Basic Linux Commands
      • Bash Scripts
      • Using the Find Command in Linux
      • Unix Pipes
      • Process and Highlight JSON with jq
      • Using the Bash History
      • Bash Multiprocessing
    • Deployment
      • PyInstaller: Create An Executable From Python Code
      • How To Use Docker To Containerize Your Python Project
      • Automatically Build and Deploy Your Python Application with CI/CD
      • Guerrilla Scale Your Web Application
    • Data Science
      • Jupyter Notebook
      • NumPy: Getting Started Tutorial
    • Python Learning Resources
  • Python Courses
  • Blog
  • Login / Register