Search code examples
pythonlistdiscorddiscord.py

Weird list in Python


I was trying to fetch a member of my discord server using discord.py. Using the guild.members I was iterating over it, and it returned me the names of the members, but then I printed it directly and I got something like this:

[<Member id=102833403109497170 name='Xiaoling' discriminator='147' bot=False nick=None guild=<Guild id=102393565654216714 name='DarkFuture' chunked=True member_count=22>>, <Member id=94117068084664839 name='Rishit' discriminator='0184' bot=False nick=None guild=<Guild id=1023935685654216714 name='DarkFuture' chunked=True member_count=22>>, <Member id=9417194317169792 name='麦わら帽子・Zoro' discriminator='905' bot=False nick=None guild=<Guild id=102393565654216714 name='DarkFuture' chunked=True member_count=22>>]

Is this a List? I checked its type, and it said list, but it didn't look like a list to me. If I paste it directly in the code editor, there's an error highlighting, and if I run it, it gives me a syntax error. What is this? How is Python iterating over it?

I just found a weird list in Python which I don't know what is and I needed the information.


Solution

  • Take a look at the class Member

    class Member:
        def __init__(self,id,name,somethingElse=True):
            self.id = id
            self.name = name
            self.somethingElse = somethingElse
    
        def addExtraValue(self,extra):
            self.extra = extra
        
        def __repr__(self):
            return "<id = {}, name = '{}'>".format(self.id, self.name)
    

    Here, the Member class has its own attributes like id, name, etc.

    Let's create a list of this class

    m1 = Member(1,'name 1')
    m1.addExtraValue(15)
    m2 = Member(2,'name 2', False)
    
    members = [m1,m2]
    

    When we print members at this point. It will show output like,

    [<id = 1, name = 'name 1'>, <id = 2, name = 'name 2'>]
    

    instead of

    [<__main__.Member object at 0x7fb9c093e4c0>, <__main__.Member object at 0x7fb9c07e8130>]
    

    It is due to the def __repr__(self) function in class, which is used to create custom output.

    I hope this will clear the confusion regarding the print of < mark in the output.

    Then, Class attributes are not iterable, hence we can not directly iterate over it or can not access the attributes as a list (i.e. member[key] is not supported).

    To solve this issue you can use the eval method as shown below.

    possibleKeys = ['id','name','somethingElse','extra']
    for member in members:
        for key in possibleKeys:
            try:
                value = eval('member.{}'.format(key))
            except:
                value = 'Not Available'
            print("{} => {}".format(key,value))
        print()
    

    The eval is wrapped in try and catch because the extra attribute is not necessary to be available in all class objects.

    I hope this will clear the way to iterate over class objects to get other attributes.