How to change not operand behaviour

Question:

I dont know if this is posible but I want something like this pseudo code:

switch='.csv'
switch= not switch
print(switch) 
#output=.json
switch=not switch 
print(switch) 
#output =.csv

I’ve been reading about overrinding the __bool__ dunder method or the __neg__ dunder method but honestly I don’t have any idea on how to actually make it real…I want to do this just to understand better how classes works not necesarily to apply it to a project.

Asked By: Christian

||

Answers:

As Barmar pointed out, you’ll need to define a user-defined class to make it real using dunder methods.

__bool__ will not work here because the return value of the bool method must have type bool (i.e. be True or False) (see here). But you can use - by implementing the __neg__ method on a user-defined class:

class FileExt:

    def __init__(self, value):

        self.val = value

    def __repr__(self):

        # When class instance is printed, print val attribute
        return self.val

    def __neg__(self):

        if self.val == '.csv':
            return FileExt('.json')
        elif self.val == '.json':
            return FileExt('.csv')
        else:
            raise ValueError("self.val should be '.csv' or '.json'")


my_file_ext = FileExt('.csv')
my_file_ext = -my_file_ext
print(my_file_ext)
my_file_ext = -my_file_ext
print(my_file_ext)

Output:

.json
.csv

It is important to remember that my_file_ext now has type FileExt, so certain basic operations may not work as expected. For example, I guess you are likely to want to concatenate the file extensions to other strings to make file names, etc., but with the above class definition this won’t work:

my_file_ext = FileExt('.csv')
print('my_file' + my_file_ext)

outputs

TypeError: can only concatenate str (not "FileExt") to str

To replicate string concatenation, you’d need to define the __add__ and __radd__ methods by adding the following to the class declaration:

    def __add__(self, any_string):

        if isinstance(any_string, str):
            return self.val + any_string
        else:
            raise TypeError(f"Can't add {self.__name__} instance to non-string value!")

    def __radd__(self, any_string):

        if isinstance(any_string, str):
            return any_string + self.val
        else:
            raise TypeError(f"Can't add {self.__name__} instance to non-string value!")

Now,

my_file_ext = FileExt('.csv')
print('my_file' + my_file_ext)

outputs

my_file.csv
Answered By: ljdyer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.