Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing message when class variable is called

Tags:

python

I'm using a 2 python class as configuration file. One of them contain old parameters (deprecated) and I would like to display a message if a deprecated param is used.

Here is how I used the different class:

config_backup.py

class _ConfigBackup:
    PARAM1 = 'a'
    PARAM2 = 'b'

config_new.py

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

cfg = Config

Then I can call cfg and have result like this:

>>> cfg.PARAM3
'c'
>>> cfg.PARAM1
Parameter PARAM1 is deprecated.
'a'

The function or method would look like this I think:

def warning(param):
    print(f"Parameter {param.__name__} is deprecated.")
    return param

I am not exactly sure if this is possible, maybe by using decorator or with statement, any idea ?

like image 367
Yohann L. Avatar asked Jan 07 '21 15:01

Yohann L.


People also ask

How do you print a class variable in Python?

How to Print the Type of a Variable in Python. To get the type of a variable in Python, you can use the built-in type() function. In Python, everything is an object. So, when you use the type() function to print the type of the value stored in a variable to the console, it returns the class type of the object.

What the __ repr __ function does?

Python __repr__() function returns the object representation in string format. This method is called when repr() function is invoked on the object. If possible, the string returned should be a valid Python expression that can be used to reconstruct the object again.

Which method is used to print the value of a variable?

Using printf function, we can print the value of a variable. In order to print the variable value, we must instruct the printf function the following details, 1.


Video Answer


2 Answers

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)
like image 168
big_bad_bison Avatar answered Oct 28 '22 23:10

big_bad_bison


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'
like image 20
BoarGules Avatar answered Oct 29 '22 00:10

BoarGules