0

How can I implement a static property or method-pair in Python using a sharable and accessible static attribute?

class StaticClass:
    __static_attr: str

    @classmethod
    def set(cls, input__):
        cls.__static_class = input__

    @classmethod
    def get(cls):
        return cls.__static_attr


StaticClass.set("Hello!")
print(StaticClass.get())

Output:

C:\Users\pc\AppData\Local\Microsoft\WindowsApps\python3.7.exe C:/Users/pc/source/repos/main.py
Traceback (most recent call last):
  File "C:/Users/pc/source/repos/main.py", line 15, in <module>
    print(StaticClass.get())
  File "C:/Users/pc/source/repos/main.py", line 11, in get
    return cls.__static_attr
AttributeError: type object 'StaticClass' has no attribute '_StaticClass__static_attr'

Process finished with exit code 1

Edit: The above source code has a typo in set(). If that typo is fixed, the code runs perfectly.

However, in the case of my original source code, that attribute was a List[str]. In that case, the program only runs only if the attribute is initialized through a pair of square brackets [].

import os
from typing import List


class SearchFilesInTheDirectory:
    __file_list: List[str] = []

    @classmethod
    def do_indexing_of_files(cls, path, file_extension):
        for root, dirs, files in os.walk(path):
            for file in files:
                if file.endswith(file_extension):
                    cls.__file_list.append(os.path.join(root, file))

    @classmethod
    def get_files_list(cls):
        return cls.__file_list

    @classmethod
    def printf(cls):
        if cls.__file_list is not None:
            for file in cls.__file_list:
                print(file)
        else:
            print("directory is empty")

    @classmethod
    def write_to_file(cls, file_name):
        if cls.__file_list is not None:
            with open(file_name, 'w') as f:
                for f_name in cls.__file_list:
                    f.write("%s\t%s\n" % f_name)
        else:
            print("directory is empty")
user366312
  • 16,949
  • 65
  • 235
  • 452
  • Your example has a typo in the set method. Should be __static_attr. It works as expected then – Keverly Apr 08 '21 at 21:31
  • In Python, we are consenting adults. What's wrong with just using a normal class attribute with a normal name (without leading underscores) for your purpose? – Karl Knechtel Apr 08 '21 at 21:39
  • Are you sure that you want to use attribute names starting with double underscore? You might have a look at https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-single-and-double-underscore-before-an-object-name. Also, it looks like you are trying to mimic some other language in Python. Maybe it would be simpler to ask about your actual problem, there might be ways to do it you didn't envision; – Thierry Lathuille Apr 08 '21 at 21:40

1 Answers1

1

It would be a better idea is to initialize the class static variable, not just declare its type. This way you would be able to call get even before set, and have it return a default value:

class StaticClass:
    __static_attr = ""

    @classmethod
    def set(cls, input__):
        cls.__static_attr = input__

    @classmethod
    def get(cls):
        return cls.__static_attr


StaticClass.set("Hello!")
print(StaticClass.get())

Also, it seems like your original code had a typo, as a result of which set method was assigning to a variable other than the one you were declaring (__static_class instead of __static_attr). Because of that, and because the static variable was not initialized, your get method failed.

Amitai Irron
  • 1,973
  • 1
  • 12
  • 14
  • 1
    The error occurred because the value wasn't actually getting set before the get attempt, because of the typo. Initialization isn't actually necessary, although it's probably a good idea. – Karl Knechtel Apr 08 '21 at 21:39
  • The original source code has a typo in `set()`. If that type is fixed, the code runs perfectly. However, in the case of my original source code, that attribute was a `List[str]`. In that case, the program only runs only if the attribute is initialized through a pair of square brackets `[]`. – user366312 Apr 08 '21 at 21:53