Makzan
Makzan

我管理世界職業技能競賽之網站技術項目、舉辦本地設計與開發賽事、開課分享技術心得。一個用網頁來表達自己的作家。

Lists with attribute names: An introduction to Python's NamedTuple

NamedTuple, as its name suggests, is also a type of Tuple, so some features of Tuple can also be applied to NamedTuple, such as accessing by [index] or [start:end]. Or unpack and other functions, examples are as follows. The ISOCalendar introduced earlier was also upgraded from the original Tuple to NamedTuple in Python 3.9, and the Tuple can be seen directly by printing, but each attribute has a name.

In Python, we often need to use Dict dictionary to store data . As long as each record has different properties, the Dict type is the natural choice. However, the flexibility of Dict also brings the disadvantage that if the wrong index (Key) is used during storage, an error will occur during acquisition.

 sample_contact = {    
    "name": "Tom",
    "email": "tom@example.com",
    "birth_month": 10
}

print(sample_contact["name"]) # Result: Tom
print(sample_contact.get("name", "Untitled")) # Result: Tom

Of course, we can also use the get function of Dict to ensure that when the value is retrieved, even if the Key does not exist accidentally, it will not report an error to the App.

 sample_contact = {
    "name": "Tom",
    "email": "tom@example.com",
    "birth_month": 10
}

print(sample_contact.get("name", "Untitled")) # Result: Untitled
print(sample_contact["name"]) # Result: error

This solves the error reporting problem, but does not solve the problem that the information cannot be accessed due to the wrong key. At this point, the NamedTuple type can be used instead.

Introducing NamedTuple

NamedTuple first needs to define a template, that is, what attributes this record has, which needs to be formulated in advance. For example, a CRM system, assuming that each guest records a name (name), email (email), birthday month (birth_month) and so on. We can use the following code to define this customer record.

 from collections import namedtuple

Contact = namedtuple("Contact", "name, email, birth_month")

The above is a template, but there are no records generated from this template yet.

Define templates and generate entities

Generate record

Then, when we need a new record. then you can use:

 sample_contact = Contact("Tom", "tom@example.com", birth_month=10)

In this way, we have generated an entity from the Customer template.

Note that our template names start with an uppercase letter, and each entity starts with a lowercase letter.

If we print out this customer, Python will also list the name of each attribute in it.

 print(sample_contact) 
# Result: Contact(name='Tom', email='tom@example.com', birth_month=10)

Tuple feature and ISO Calendar example

NamedTuple, as its name suggests, is also a type of Tuple, so some features of Tuple can also be applied to NamedTuple, such as accessing by [index] or [start:end]. Or unpack and other functions, examples are as follows.

The ISO Calendar introduced before has also been upgraded from the original Tuple to NamedTuple in Python 3.9 , and the Tuple can be seen directly by printing, but each attribute has a name.

The following sample code, after obtaining the ISO Calendar value of today's date, print out, view the type, access by attribute name, press [index] to get the value, etc. You can also use the unpack method that is used in ISO Calendar in the past. For example, in this example, the three values of ISOCalendar are loaded into three variables of year, week, and weekday.

 import datetime

today_iso_calendar = datetime.date.today().isocalendar()

print(today_iso_calendar)
print("type", type(today_iso_calendar))

print("week", today_iso_calendar.week)
print("year", today_iso_calendar[0])

year, week, weekday = today_iso_calendar

print(f"{year}-W{week}-{weekday}")

operation result:

 datetime.IsoCalendarDate(year=2022, week=4, weekday=3)
type <class 'datetime.IsoCalendarDate'>
week 4
year 2022
2022-W4-3

So NamedTuple is a type between a Tuple read-only list and a Dict dictionary.

operation result

Reduce the chance of mistakes

When getting the properties of this client, because of the direct use of .name, etc. to access, instead of using the string as an index. This also ensures that we use the correct properties, because if we make a careless typo, the code editor will throw an error right away, rather than wait until runtime.

 sample_contact = Contact("Tom", "tom@example.com", birth_month=10)
print(sample_contact.name) # Result: Tom

This reduces the likelihood of such errors in running the program when we deliver it to others. It also makes the program more stable and clearer when the program is printed.


Makzan by Mai Mai , 2022-01-26.

CC BY-NC-ND 2.0

Like my work?
Don't forget to support or like, so I know you are with me..

Loading...
Loading...

Comment