vendredi 21 avril 2017

Using `if object:` with a python class

I am trying to do a system in Python 3 where a class stocks data, and one of the things the class may store is an other class.

I want that system to return a dict() containing all the data. The reason I do not use a dict() to store all that in the first place, is that I need to modify the data a lot, and class methods are way more practical for this situation.

All of that is not a problem, and I have something like this:

class Attachment:
    def __init__(self):
        self.type = None
        self.url = None

    def get_dict():
        data = {}
        if self.type:
            data['type'] = self.type
        if self.url:
            data['url'] = self.url

class Message:
    def __init__(self):
        self.text = None
        self.attachment = Attachment()

    def get_dict():
        data = {}
        if self.text:
            data['text'] = self.text
        if self.attachment:
            data['attachment'] = self.attachment.get_dict()

I have very specific types, and I do not need the system to be really more modular (I know all the variables any class might contain, and the get_dict() can get them all easily without being too long)

But here if I call the get_dict() of the Message class, I will get:

{'attachment': {}}

Which is logical: Message.text is None, same thing for Attachment.type and Attachment.url, but Message.attachment is NOT None, since it is a Attachment object.

Now, I need empty class objects, like this Message.attachment, to be removed. What I do, is that instead of checking the class objects, I check their get_dict() (since I always know which one they are, I do not risk having a str().get_dict() happen) like so:

class Attachment:
    def get_dict():
        if self.url:
            data['url'] = self.url
        return None if data=={} else data

class Message:
    def get_dict():
        tmp = self.attachment.get_dict()
        if tmp:
            data['attachment'] = tmp

So that I have a empty dict when calling Message.get_dict()

I tried to overload the Attachment.__eq__() to return None if Attachment.get_dict() returns an empty list

class Attachment:
    def __eq__(self, other):
        return self.get_dict() == other

The idea was that I could just, then, do if self.attachment: in Message.get_dict() ... but that does not work.

However, if self.attachment == None: works.

I tried this in the python console, and this is what I got:

>>> class A:
...     def __init__(self):
...             self.a = None
...     def __eq__(self, other):
...             return self.a == other
>>> test = A()
>>> test == None
>>> test
<__main__.A object at 0x102d43748>
>>> print('a') if test else print('b')

I understand that the __eq__() method only works for "rich comparaisons" as the python doc calls it. But is there a way to make this work for all if checks?

The whole method I used is also most certainly bad, so I welcome any suggestion, or explanation of what good practice would be here.


0 commentaires:

Enregistrer un commentaire