1

I want to print a class attribute, part of a list of instances, only if this attribute exist

i created a class name Guitarist, that includes a name attribute, and otherItems (which usually is a dictionary for the user to add additional data such as band, guitar etc...). It adds the the class to a list (i hope i am not confusing terms) i created another class called FenderGuitarist which inherits Guitarist, and adds an attribute of guitar to the constructor. How do i change the print function, which gets the guitarist list as a parameter, that only if it identifies a guitar attribute, it prints it? note: please ignore the fact that a user can add guitar attribute to the otherItems dicionary as well.

guitarists = []

class Guitarist:
    playing_instrument = "guitar"

    def __init__(self, name, otherItems=None):
        self.name = name
        self.otherItems = otherItems
        guitarists.append(self)

    def __str__(self):
        return "Guitarist"

    def get_playing_instrument(self):
        return self.playing_instrument

def print_list(list):
    for item in list:
        print(f"name {item.name}",  end="")
        if item.otherItems is not None:
            print(":")
            for key,value in item.otherItems.items():
                print(key, value)
            print()

class FenderGuitarist(Guitarist):
    def __init__(self, name, otherItems=None):
        Guitarist.__init__(self, name, otherItems=None)
        self.guitar = "Fender"

    def __str__(self):
        return "Fender Guitarist"

print result: name, guitar(if exist) and the otherItems of the dicionary for each item in the list

So for this code i would want the print funcion to identify only tomMisch item as having a guitar attribute and then print it. for the others just print name and everything in the otherItems dicionary:

from classes import *


johnMayer = Guitarist("John Mayer", {"favorite guitar": "Fender/PRS"})
dictJimmy = {"band": "Led Zeppelin", "favorite guitar": "Gibson"}
jimmyPage = Guitarist("Jimmy Page", dictJimmy)
tomMisch = FenderGuitarist("Tom Misch")

print_list(guitarists)

2 Answers2

1

There are lots of possible solutions. One (hacky) solution is to use hasattr:

def print_list(list):
    for item in list:
        if not hasattr(item, 'guitar'):
            continue

        print(f"name {item.name}",  end="")
        if item.otherItems is not None:
            print(":")
            for key,value in item.otherItems.items():
                print(key, value)
            print()

What we do here is ask "does this item have an attribute called guitar?" If not, continue to the next iteration of the loop.

I'm happy to share more solutions if this one doesn't cut it.

Paymahn Moghadasian
  • 9,301
  • 13
  • 56
  • 94
  • 1
    [`hasattr`](https://docs.python.org/3/library/functions.html#hasattr) might be better. – wwii Apr 07 '19 at 14:06
  • Yup, `hasttr` is definitely better. Should I edit the posted solution? I'm not sure what the standard etiquette for situations like this is. – Paymahn Moghadasian Apr 07 '19 at 14:08
  • 1
    You can always change your answer. If a comment points out an improvement or a deficiency you are free to change it. Sometimes if a comment suggest an alternate I like but the answer has already been accepted I will add the alternate and leave the original. – wwii Apr 07 '19 at 14:16
0

i've edited a bit the code in the question above so now the Fender is part of the constructor but not as an input.

hasattr solve the problem. i actually just wanted to add in the print_list function so it will print guitar attribute if it exists, and print all the others anyway. so the addition is:

if hasattr(item, 'guitar'):
    print(", guitar Fender")

so the entire function now looks like that:

def print_list(list):
for item in list:
    print(f"name {item.name}",  end="")
    if hasattr(item, 'guitar'):
        print(", guitar Fender")
    if item.otherItems is not None:
        print(":")
        for key,value in item.otherItems.items():
            print(key, value)
        print()