Explaining the use of underscored variables in init method in Python

The aim of this explainer💡 is to analyze underscored vars in python initializers — also known as backing field. In OOP languages, * backing field (or backing store) is a private field that stores the data exposed by a public property. Etymologically, it seems, it’s comparable with backing music, meaning providing support for the main performer

Pavol Kutaj
2 min readJun 9, 2023

1. Backing fields can be used to avoid name clash with methods and to hide implementation details

  • why _number ?
  1. avoid name clash with the method number()
  2. there is a widely accepted convention that implementation details for an object not intended for consumption/manipulation by clients of an object do start with an _
  • you can access them in the REPL with underscore, too
  • very handy for debugging in early testing
  • not recommended for prod code
class Flight:

def __init__(self, number):
self._number = number

def number(self):
return self._number

2. Backing fields can also be used accompanied with None as their default value in cases a method that is backed should run only ONCE

  • Look at the following code — Will read_only_keys run only once? I need that. It creates a unique key that I don't want to change each time the property is accessed!
class Client:
def __init__(self, client_tag: str, ticket_id: str):
self.client_tag = client_tag
self.org_id = handlers.get_org_id(client_tag)
self.ticket_id = ticket_id
self.dev_server = f"{self.client_tag.replace('_', '-')}-dev1.net"
self.prod_server = f"{self.client_tag.replace('_', '-')}-prod1.net"

@property
def read_only_keys(self):
return self.get_keys(self, KeyType.READ_ONLY)
  • The read_only_keys property will not run only once. Each time you access the read_only_keys property, the get_keys method will be called with KeyType.READ_ONLY as an argument and a new key will be generated.
  • To generate a single key and store it, you can modify the code to store the result of the first call to get_keys in an instance variable and return that value for subsequent accesses to the read_only_keys property.
  • Here is an example of how you can modify the ClientIglu class to store the key in an instance variable (note the backed property _read_only_key !):
class Client:
def __init__(self, client_tag: str, ticket_id: str):
self.client_tag = client_tag
self.org_id = handlers.get_org_id(client_tag)
self.ticket_id = ticket_id
self.dev_server = f"{self.client_tag.replace('_', '-')}-dev1.net"
self.prod_server = f"{self.client_tag.replace('_', '-')}-prod1.net"
self._read_only_key = None

@property
def read_only_keys(self):
if not self._read_only_key:
self._read_only_key = self.get_keys(self, KeyType.READ_ONLY)
return self._read_only_key
  • In this modified version of the class, the first time you access the read_only_keys property, the get_keys method will be called with KeyType.READ_ONLY as an argument and the result will be stored in the _read_only_key instance variable.
  • Subsequent accesses to the read_only_keys property will return the value stored in the _read_only_key instance variable without calling the get_keys method again.

3. sources

--

--

No responses yet