简体   繁体   中英

How to put “if the function has been called this many times” in Python?

So I'm designing a hangman game using Python and Kivy and I want to add a win/lose option.

one of the functions I've defined is Button_pressed which hides the button if it's been pressed but I want the function man_is_hung() to have something that says "if the button has been pressed 6 times, show "game over"."

Would someone please help me?

 def button_pressed(button):
        for (letter, label) in CurrentWord:
            if (letter.upper() == button.text): label.text=letter 
        button.text=" " # hide the letter to indicate it's been tried

def man_is_hung():
    if button_pressed(button)

Use a decorator :

Example:

class count_calls(object):
    def __init__(self, func):
        self.count = 0
        self.func = func
    def __call__(self, *args, **kwargs):
        # if self.count == 6 : do something
        self.count += 1
        return self.func(*args, **kwargs)

@count_calls
def func(x, y):
    return x + y

Demo:

>>> for _ in range(4): func(0, 0)
>>> func.count
4
>>> func(0, 0)
0
>>> func.count
5

In py3.x you can use nonlocal to achieve the same thing using a function instead of a class:

def count_calls(func):
    count = 0
    def wrapper(*args, **kwargs):
        nonlocal count
        if count == 6:
            raise TypeError('Enough button pressing')
        count += 1
        return func(*args, **kwargs)
    return wrapper

@count_calls
def func(x, y):
    return x + y

Demo:

>>> for _ in range(6):func(1,1)
>>> func(1, 1)
    ...
    raise TypeError('Enough button pressing')
TypeError: Enough button pressing

Here's a way to have static variables in functions that doesn't involve globals or classes:

def foobar():
    foobar.counter = getattr(foobar, 'counter', 0)
    foobar.counter += 1
    return foobar.counter

for i in range(5):
    print foobar()

You could store the button as a class like so:

class button_pressed(Object):
    def __init__(self):
        self.num_calls = 0

    def __call__(self, button):
        self.num_calls += 1
        if self.num_calls > 6:
            print "Game over."
            return None
        else:
           # Your regular function stuff goes here.

This is basically a manual decorator, and while it might be a bit complicated for what you are trying to do this is an easy way to do bookkeeping on a function.

Really, the correct way to do this kind of thing is to use a decorator that takes a parameter for the number of times you want the function to be able to be called and then applies the above pattern automatically.

Edit: Ahh! hcwhsa beat me to it. His solution is the more general one I was talking about above.

ummmm

num_presses = 0
def button_pressed(button):
    global num_presses
    num_presses += 1
    if num_presses > X:
         print "YOU LOSE SUCKA!!!"
    for (letter, label) in CurrentWord:
        if (letter.upper() == button.text): label.text=letter 
    button.text=" " # hide the letter to indicate it's been tried

would be one way of doing it ... Im kind of suprised you have made it this far without knowing how to save simple states.

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