Printing message when class variable is called

One method you could use with the @property decorator

class Config(_ConfigBackup):
    PARAM3 = 'c'
    PARAM4 = 'd'
    __PARAM1 = _ConfigBackup.PARAM1

    @property
    def PARAM1(self):
        print(f"Parameter PARAM1 is deprecated.")
        return Config.__PARAM1

cfg = Config()

print(cfg.PARAM1)
print(cfg.PARAM2)
print(cfg.PARAM3)
print(cfg.PARAM4)

Output:

Parameter PARAM1 is deprecated.
a
b
c
d

EDIT:

Another option is modifying __getattribute__:

class Config(_ConfigBackup):
    PARAM3 = 'c'
    PARAM4 = 'd'

    DEPRECATED = ['PARAM1', 'PARAM2']

    def __getattribute__(self, item):
        if not item == 'DEPRECATED' and item in Config.DEPRECATED:
            print(f"Parameter {item} is deprecated.")
            return object.__getattribute__(self,item)

Here is a proof-of-concept solution that meets the objection of having too many properties to be workable.

class Config:
    def __init__(self):
        self.deprecated = {'PARAM1': 'a', 'PARAM2': 'b'}
        self.nondeprecated = {'PARAM3': 'c', 'PARAM4': 'd'}
    def __getattr__(self, parmname):
        if parmname in self.__dict__["deprecated"]:
            print(f"{parmname} is deprecated")
            return self.__dict__["deprecated"][parmname]
        return self.__dict__["nondeprecated"][parmname]

>>> c = Config()
>>> c.PARAM1
PARAM1 is deprecated
'a'
>>> c.PARAM2
PARAM2 is deprecated
'b'
>>> c.PARAM3
'c'

I didn't put the deprecated parameters in a separate class because that would complicate the example unnecessarily. And real-world code would need to be able to cope with attempts to name a nonexistent parameter, and not do this:

>>> c.PARAM5
Traceback (most recent call last):
  File "<pyshell#105>", line 1, in <module>
    c.PARAM5
  File "<pyshell#100>", line 9, in __getattr__
    return self.__dict__["nondeprecated"][parmname]
KeyError: 'PARAM5'

Tags:

Python