AttributError

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Eragpm
User
Beiträge: 14
Registriert: Mittwoch 10. Juni 2020, 23:20

Code: Alles auswählen

class ShopCardGui:
    def __init__(self, surface, shopcard):
        self.surface = surface
        self.shopcard = shopcard
        self.font = pygame.font.SysFont('Arial', 25)

    def paint_shop_card(self, x, y):
        rect = pygame.draw.rect(self.surface, WHITE, (x, y, 190, 250))
        self.surface.blit(self.font.render(self.shopcard.name, True, (255, 0, 0)), (x, y))# problem ist hier
        self.surface.blit(self.font.render(str(self.shopcard.energycost), True, (255, 0, 0)), (x, y+220))# und hier
        return rect
        
class ShopCard:
    def __init__(self, energy_cost, name=str):
        self.name = name
        self.energy_cost = energy_cost
        
class Board
def create_shop_cards(board_size=int):
    shop_card_deck = list()
    for i in range(10000):
        if i <= 3000:
            shop_card_deck.append(ShopCard(2, "Snack"))  # doppelt so viel energie ausgeben wie man bekommt
        elif 3000 < i <= 6000:
            shop_card_deck.append(ShopCard(random.randint(1, board_size),"Landfahrzeug"))
        elif 6000 < i <= 9000:
            shop_card_deck.append(ShopCard( random.randint(1, board_size),"Wasserfahrzeug"))
        elif 9000 < i <= 10000:
            shop_card_deck.append(ShopCard(board_size, "neue Quest"))
    return shop_card_deck
        
        
        
es kommt immer der Fehler
AttributeError: 'str' object has no attribute 'name'
Ursache ist wo ich oben hingeschrieben habe
Ich weis einfach nicht mehr was ich da jetzt noch machen sollen wenn ich den type(self.shopcard.name) abfrage ist es ein string bei type(self.shopcard) ist es Shopcard.Shopcard
wenn ich self.shopcard.name und self.shopcard.elexiercost mit einem beliebigen String ersetze funktiert es
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Fehlermeldung ist da sehr eindeutig - was du denkst was shopcard ist, ist nicht, was du uebergibst. Du zeigst nicht, wie du ShopCardGui erzeugst, aber da irgendwo gibst du halt das falsche rein.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Bitte den relevanten Code und den kompletten Traceback posten.
Es ist wenig sinnvoll, als Defaultwerte den Typ str oder int zu setzen.
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

Eragpm hat geschrieben: Mittwoch 29. Juni 2022, 14:48 es kommt immer der Fehler
AttributeError: 'str' object has no attribute 'name'
Ursache ist wo ich oben hingeschrieben habe
Ich weis einfach nicht mehr was ich da jetzt noch machen sollen wenn ich den type(self.shopcard.name) abfrage ist es ein string bei type(self.shopcard) ist es Shopcard.Shopcard
wenn ich self.shopcard.name und self.shopcard.elexiercost mit einem beliebigen String ersetze funktiert es
In deinem Code-Fragment sehe ich diesen Fehler nicht.
Der Fehler sagt aus, dass du ein Attribut "name" von einem String-Objekt ansprichst, also sowas wie 'string'.name.
Was dieses String-Objekt bei dir ist, siehst du am Besten am Error-Trace.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Eragpm: Neben der Anmerkung von Sirius3, dass der Typ kein sinnvoller Defaultwert ist, ist es auch nicht sinnvoll einen Defaultwert für Argumente zu haben die gar nicht optional sind. So eine `ShopCard` braucht ja anscheinend einen Namen, damit sie sinnvoll funktioniert.

Wenn das Problem gelöst ist, läuft der Code gleich in das nächste: `ShopCard`-Objekte haben kein Attribut `energycost`. Da fehlt ein Unterstrich.

Bei `create_shop_cards()` ist bei den Vergleichen in den ``elif``-Zweigen die Unzergrenze überflüssig, weil diese Teilbedingung durch den vorherigen Zweig natürlich immer wahr ist. Ich finde das auch nicht so sinnvoll für jeden Schleifen Durchlauf diesen Test zu machen der immer ein paar tausend mal hintereinander gleich ausgeht. Ich würde da eher eine Schleife über die Anzahlen und die Namen der einzelnen Shopkartenarten machen:

Code: Alles auswählen

def create_shop_cards(board_size):
    deck = []
    for card_count, create_energy_cost, name in [
        (3001, lambda: 2, "Snack"),
        (3000, lambda: random.randint(1, board_size), "Landfahrzeug"),
        (3000, lambda: random.randint(1, board_size), "Wasserfahrzeug"),
        (999, lambda: board_size, "neue Quest"),
    ]:
        deck.extend(
            ShopCard(create_energy_cost(), name) for _ in range(card_count)
        )

    assert len(deck) == 10_000, f"deck length: {len(deck)}"

    return deck
Falls Dir die 3001 und die 999 komisch vorkommen: Das ist das was der ursprüngliche Code auch macht. Das ist leichter sichtbar wenn man es direkt als Zahl hin schreibt, statt es indirekt als Vergleich auszudrücken.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten