简体   繁体   中英

How do I call a method properly?

I am working on a game and have met a problem. I am getting a error when trying to call the draw_red_team_one() method but I can't see the reason why.

It says missing 1 required positional argument: self so I checked it out and found out that I had to write RT = red and then self.draw_red_team_one() so I fixed that but I still get the same error.

class red:
    def __init__(self):
        self.x_y = [130, 290]
        self.height_width = [10, 3]
        self.red = [255, 0, 0]

    def draw_salt(self, surface, color, x, y, height, width):
        pygame.draw.rect(surface, color, ((x, y), (height, width)))

    def draw_red_team_one(self):
        self.draw_salt(screen, red, x_y[0], x_y[1], height_width[0], height_width[1])
running = True

while running:
    RT = red
    RT.draw_red_team_one()
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

I expect the full program to open a pygame window and print a white horizontal line with a red box on the top left side. The program just throws me a error.

With RT = red you assigned the class to RT, but draw_red_team_one is an instance method and as such it requires the positional argument self as declared in your method. If you call this method on an instance of class red , the argument is implicitely passed, so you don't notice it, but if you call it using red.draw_red_team_one() you have to pass it yourself, otherwise you get the error message, you mentioned. To put it in another way:

obj.draw_red_team_one()

is the same as:

red.draw_red_team_one(obj)

The second variant is just what Python implicitly does, when the first variant is executed.

But anyways, you will not need to reference the method in the style of red.draw_red_team_one very often. You normally only need this, if you have to pass the method as callable somewhere. Eg if you have a class with a method, that returns some info of the objects and you want to use methods like map to get the information for each object in a list. In that case, you would do something like:

map(PersonClass.name, list_of_people)

Which is the same as (in the sense that both are iterables returning the same elements):

[person.name() for person in list_of_people]

Btw. I think your code should rather look like this (haven't checked if it runs though):

class red:
    def __init__(self):
        self.x_y = [130, 290]
        self.height_width = [10, 3]
        self.red = [255, 0, 0]

    def draw_salt(self, surface, color, x, y, height, width):
        pygame.draw.rect(surface, color, ((x, y), (height, width)))

    def draw_red_team_one(self):
        # you need to add self. to reference the instance variables
        self.draw_salt(screen, self.red, self.x_y[0], self.x_y[1], self.height_width[0], self.height_width[1])

running = True

while running:
    # create an object (this creates an instance and implicitely calls __init__ which performs your initialization code)
    RT = red()
    RT.draw_red_team_one()
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM