[Tutor] Unbound Method Error

Prasad, Ramit ramit.prasad at jpmchase.com
Mon Apr 25 17:17:20 CEST 2011


Disclaimer: I have no knowledge of PyGame.

I think your original is a lack of checking types. You are calling BlueCar/GreenCar/Truck.collide regardless  of the car type. If you pass a TruckSprite to BlueCarSprite.collide it makes sense (without knowledge of PyGame) that it would fail because it expects a BlueCarSprite not a TruckSprite.

You do:
crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)


        if crash:
            for BlueCarSprite in crash: # This loops through crash
                redracersprites26.BlueCarSprite.collide(crash, playerCar)
            for GreenCarSprite in crash: # This loops through crash again
                redracersprites26.GreenCarSprite.collide(crash, playerCar)
            for TruckSprite in crash: # This loops through crash for the third time
                redracersprites26.TruckSprite.collide(crash, playerCar)


There are two other problems with this: 1) this is sending the entire list of collisions to each of these functions. 2) The way you are looping seems odd to me.
I would think you want something more like the following (UNTESTED):

crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)
if crash:
    for car in crash:
        if isinstance(car, BlueCar):
            redracersprices26.BlueCarSprite.collide(car, playerCar)
        if isinstance(car, GreenCar):
            redracersprices26.GreenCarSprite.collide(car, playerCar)
        if isinstance(car, TruckCar):
            redracersprices26.TruckCarSprite.collide(car, playerCar)

If you really want to call all 3 collide statements, then just remove the 'if isinstance(car, \w*):' line and it will call the collide for each.


Ramit



Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

From: tutor-bounces+ramit.prasad=jpmchase.com at python.org [mailto:tutor-bounces+ramit.prasad=jpmchase.com at python.org] On Behalf Of Greg Nielsen
Sent: Monday, April 25, 2011 4:37 AM
To: Steven D'Aprano
Cc: tutor at python.org
Subject: Re: [Tutor] Unbound Method Error

First and foremost, thank you Steven for your quick and well written response. It means a lot to me that you took the time out of your day to answer my question, and it has really helped me better understand what it going on.

So the full trace back for my error is as follows:

Traceback (most recent call last):
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracer26.py", line 19, in <module>
    main()
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracer26.py", line 16, in main
    redracerstates26.game(startLives)
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracerstates26.py", line 87, in game
    redracersprites26.BlueCarSprite.collide(BlueCarSprite, playerCar)
TypeError: unbound method collide() must be called with BlueCarSprite instance as first argument (got GreenCarSprite instance instead)
After reading through your explanation of unbound methods (and wrapping my head around the concept), I came up with a quick fix that lead to a new issue in my code. Here is what I think should work:

crash = pygame.sprite.spritecollide(playerCar, computerSprites, False)
        if crash:
            for BlueCarSprite in crash:
                redracersprites26.BlueCarSprite.collide(crash, playerCar)
            for GreenCarSprite in crash:
                redracersprites26.GreenCarSprite.collide(crash, playerCar)
            for TruckSprite in crash:
                redracersprites26.TruckSprite.collide(crash, playerCar)

However, the spritecollide method returns a list, which my collide method isn't expecting. The list should only contain the name of the sprite the player hit. In Python 3, the method would just pull the variable out of the list and work with it, but in Python 2, it's not expecting a list, causing an error similar to the one seen previously:

Traceback (most recent call last):
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracer26.py", line 19, in <module>
    main()
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracer26.py", line 16, in main
    redracerstates26.game(startLives)
  File "C:\Users\Greg\Documents\NetBeansProjects\Red Racer 26\src\redracerstates26.py", line 87, in game
    redracersprites26.BlueCarSprite.collide(crash, playerCar)
TypeError: unbound method collide() must be called with BlueCarSprite instance as first argument (got list instance instead)
So what really has to happen now (I think) is that the list needs to be unpacked into just a simple variable containing the name of the sprite in question. This way the method receives the name of the instance (self) in the way it was expecting to receive it. In your opinion, should I unpacked the list before passing the data into the method, or attempt to define "self" as a list? Is the latter even possible? I would think it would have to be because otherwise Python could pick a variable type which you don't want or aren't expecting it to pick and need to force it to take a certain type of input.

And thank you for pointing out the fact I could just make a CarSprite class and have subclasses (basically just a different sprite image) work with the details. You just removed over 150 lines of redundant code from my program. And once again, thank you Steven for taking the time to help me better understand the whole unbound method concept.

Greg


This communication is for informational purposes only. It is not
intended as an offer or solicitation for the purchase or sale of
any financial instrument or as an official confirmation of any
transaction. All market prices, data and other information are not
warranted as to completeness or accuracy and are subject to change
without notice. Any comments or statements made herein do not
necessarily reflect those of JPMorgan Chase & Co., its subsidiaries
and affiliates.

This transmission may contain information that is privileged,
confidential, legally privileged, and/or exempt from disclosure
under applicable law. If you are not the intended recipient, you
are hereby notified that any disclosure, copying, distribution, or
use of the information contained herein (including any reliance
thereon) is STRICTLY PROHIBITED. Although this transmission and any
attachments are believed to be free of any virus or other defect
that might affect any computer system into which it is received and
opened, it is the responsibility of the recipient to ensure that it
is virus free and no responsibility is accepted by JPMorgan Chase &
Co., its subsidiaries and affiliates, as applicable, for any loss
or damage arising in any way from its use. If you received this
transmission in error, please immediately contact the sender and
destroy the material in its entirety, whether in electronic or hard
copy format. Thank you.

Please refer to http://www.jpmorgan.com/pages/disclosures for
disclosures relating to European legal entities.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20110425/d232e529/attachment-0001.html>


More information about the Tutor mailing list