読者です 読者をやめる 読者になる 読者になる

ゆくゆくは有へと

おかゆ/オカ∃/大鹿有生/彼ノ∅有生 の雑記

せや!コイツも疲れとるやろしインタプリタ閉じたろ!

1/3の確率で「ンゴwww」と言いながら、その関数を実行せずにインタプリタを閉じてくれるクソムカつく優しいデコレータを作りました。

# coding=utf-8

import random
import functools


def bebna(function):
    @functools.wraps(function)
    def _(*args, **kwds):
        x = random.choice([False, True, True])
        if x:
            return function(*args, **kwds)
        else:
            print("ンゴwww")
            quit()
    return _


@bebna
def print_hello():
    print("Hello!")

実行例:

>>> import bebna
>>> bebna.print_hello()
Hello!
>>> bebna.print_hello()
ンゴwww

自分で作って自分で遊んで氏ねって思いました。

あまりにも実用性がないので、少し一般化しました。

import functools
import random


def may_fail(fail_action, fail_percent=10):
    if not isinstance(fail_percent, int):
        raise TypeError
    if not (0 <= fail_percent <= 100):
        raise ValueError

    random_list = [True]*(100-fail_percent) + [False]*fail_percent

    def fail_decorator(function):
        @functools.wraps(function)
        def _(*args, **kwds):
            x = random.choice(random_list)
            if x:
                return function(*args, **kwds)
            else:
                return fail_action()
        return _

    return fail_decorator

たまに失敗しうるような関数を作れます。失敗したときの挙動は関数として渡せます。

使用例

def fail_action():
    print("failed.")


@may_fail(fail_action, 50)
def test():
    print("success.")


for _ in range(20):
    test()

結果

success.
success.
success.
failed.
success.
success.
failed.
success.
success.
success.
failed.
success.
failed.
failed.
success.
success.
failed.
failed.
failed.
success.

なんかたまに失敗しそうなやつの代わりに使えそうですね(?)

あるいは、関数の中身自体は書き換えたくないけど、こいつが時々挙げる例外に対する挙動をシミュレートしたいってときに失敗率100%にし、当該例外をあげる関数を渡して、デコレートするとか、そういうのならまだ使いみちはありそうですね(ユニットテストのモジュールに既にありそう)