How to implement an optional property?

Viewed 1582

I want to set up a property only if requested explicitly. As this property will involve extra computation time, I want it initialized with None and only initializing if a calling function requests to do so.

For example:

class File:
    def __init__(self, filename, content):
         self.filename = filename
         self.content = content
         self.hash = None or self.get_hash()

    def get_hash():
          '''do some hashing there'''

I have seen some property of that kind but don't know how this could work trigger the function by calling:

my_file = File('text.txt', 'Hello there')
my_file.hash 
2 Answers

By providing .hash with a property getter, you can create exactly the behaviour you want. The actual value of hash will be 'hidden' as ._hash which is a common practice in Python:

class File:
    def __init__(self, filename, content):
         self.filename = filename
         self.content = content
         self._hash = None

    @property
    def hash(self):
          if self._hash is None:
              # do some hashing here
              self._hash = 'some hash'
          return self._hash


f = File('myfile', 'some content')
print(f.hash)

Of course, you could also have other conditions when you need the hash to be recalculated, it doesn't have to be if self._hash is None. And you could also just reset the hash when it needs to be recalculated. For example, perhaps your hash changes when .content changes:

class File:
    def __init__(self, filename, content):
         self.filename = filename
         self._content = content
         self._hash = None

    @property
    def hash(self):
          if self._hash is None:
              # do some hashing here
              self._hash = f'some hash based on {self._content}'
          return self._hash


    @property
    def content(self):
          return self.content

    @content.setter
    def content(self, value):
          self._content = value
          self._hash = None


f = File('myfile', 'some content')
print(f.hash)
f.content = 'changed content'
print(f.hash)

Try passing it as a parameter while creating the Object.

Check if the below code is suitable for you:

class File:
    def __init__(self, filename, content, request_hash=False):
         self.filename = filename
         self.content = content
         self.hash = self.get_hash() if request_hash else None

    def get_hash():
          '''do some hashing there'''

my_file = File('text.txt', 'Hello there') #No Hash is generated
my_file = File('text.txt', 'Hello there', True) #Hash will be generated
Related