22

現在fab -f check_remote.py func:"arg1","arg2"...、fab remote の実行に使用しています。

bool 引数を送信する必要がありますが、True/False は文字列引数になります。bool 型として設定するにはどうすればよいですか?

4

10 に答える 10

14

私は関数を使用します:

def booleanize(value):
    """Return value as a boolean."""

    true_values = ("yes", "true", "1")
    false_values = ("no", "false", "0")

    if isinstance(value, bool):
        return value

    if value.lower() in true_values:
        return True

    elif value.lower() in false_values:
        return False

    raise TypeError("Cannot booleanize ambiguous value '%s'" % value)

次に、タスクで:

@task
def mytask(arg):
    arg = booleanize(arg)
于 2013-03-11T22:11:00.630 に答える
5

問題の func が "if argN is True:" の代わりに "if argN:" を使用してブール値が true かどうかをテストする場合、False には ""、True には "anything" を使用できます。

参照: http://docs.python.org/library/stdtypes.html#truth-value-testing

于 2012-07-25T02:18:51.613 に答える
5

すべてのタスクでパターンを一貫して使用する場合 (「false」、「true」はブール値)、ファブリック タスクをラップしてすべてのタスクに適用できます。

このパッケージを使用できます (私が作成): https://pypi.python.org/pypi/boolfab/

ここに(本質的に)ソースがあります:

from fabric.api import task as _task

def fix_boolean(f):
    def fix_bool(value):
        if isinstance(value, basestring):
            if value.lower() == 'false':
                return False
            if value.lower() == 'true':
                return True
        return value

    @wraps(f)
    def wrapper(*args, **kwargs):
        args_ = [fix_bool(arg) for arg in args]
        kwargs_ = {k: fix_bool(v) for k,v in kwargs.iteritems()}
        return f(*args_, **kwargs_)

    return wrapper


def task(f):
    return _task(fix_boolean(f))

次のようになります。

@task
def my_task(flag_a, flag_b, flag_c)
   if flag_a:
       ....

「ブーリアン化」引数で各タスクを汚染することなく。

于 2014-01-15T13:37:00.843 に答える
3

より良い方法は、次を使用することast.literal_evalです。

from ast import literal_eval

def my_task(flag):
    if isinstance(flag, basestring): # also supports calling from other tasks
        flag = literal_eval(flag)

これは「はい」や「いいえ」などの値を考慮していませんが、eval...

于 2013-06-03T07:56:19.400 に答える
1

デコレータを使用してこれを解決しました。デコレータを使用することで得られる柔軟性と明示性が気に入っています。

コードの要点は次のとおりです。

import ast
from fabric import utils
from fabric.api import task
from functools import wraps


def params(*types, **kwtypes):
    def decorator(function):
        @wraps(function)
        def wrapper(*args, **kwargs):
            new_args = ()
            for index, arg in enumerate(args):
                new_args += __cast(arg, types[index]),
            for kwarg in kwargs:
                kwargs[kwarg] = __cast(kwargs[kwarg], kwtypes[kwarg])
            return function(*new_args, **kwargs)
        return wrapper
    return decorator


def __evaluate(arg):
    try:
        return ast.literal_eval(arg)
    except:
        return str(arg)


def __cast(arg, arg_type):
    try:
        return arg_type(__evaluate(arg))
    except:
        utils.abort("Unable to cast '{}' to {}".format(arg, arg_type))

コードで使用すると、次のようになります。

@task
@params(int, bool, arg1=int, arg2=bool)
def test(arg1, arg2):
    print type(arg1), arg1
    print type(arg2), arg2

これは、適切なパラメーターを使用して fab 経由で呼び出すと次のようになります。

fab test:0.1,1
<type 'int'> 0
<type 'bool'> True

fab test:5,arg2=False
<type 'int'> 5
<type 'bool'> False

fab test:arg1=0,arg2=false
<type 'int'> 5
<type 'bool'> True

注:最後の例では、"false" が True です。これは Python で予期される動作ですが、自然に直観に反する場合があります。False を int として渡す場合と同様に、python では int(False) == 0 として 0 にキャストされます。

以下は、fab を介して不適切なパラメータで呼び出すと次のようになります。

fab test:Test,False
Fatal error: Unable to cast 'Test' to <type 'int'>

Aborting.
于 2015-11-17T04:19:43.087 に答える
1

私の fabfiles では、次のことを行います。

TRUTHY = [True, 1, '1', 'true', 't', 'yes', 'y']

@task
def my_task(my_arg=True):
    if my_arg in TRUTHY:
         # do stuff
    else:
         # do other stuff

もちろん、これは TRUTHY にない値はすべて実質的に であることを意味しますFalseが、これまでのところ、これ以上複雑なものは必要ありません。

于 2014-04-08T17:13:46.857 に答える
1

ユーザーが「False」を渡すと、クレイグとアリの回答は真の値になります(これについてはアリの回答の方が明確です)

eval() を使用すると、文字列「True」と「False」は正しいブール値に評価されますが、デフォルト値を使用している場合は、それらがブール値ではなく文字列であることを確認する必要があります。

def myfunc(arg1="True", arg2=False):
    arg1 = eval(arg1)
    arg2 = eval(arg2) #error
于 2012-08-22T19:31:46.180 に答える
0

これは、 https://gist.github.com/mgedmin/f832eed2ac0f3ce31edfに基づく作業バージョンです。古いバージョンとは異なり、これは実際にはすべての可能なデコレータ パラメータとタスク エイリアスを尊重します。

from functools import wraps
from fabric import tasks

def fix_boolean(f):

    true_values = ("yes", "true", "1")
    false_values = ("no", "false", "0")

    def fix_bool(value):
        if isinstance(value, basestring):
            if value.lower() in false_values:
                return False
            if value.lower() in true_values:
                return True
        return value

    @wraps(f)
    def wrapper(*args, **kwargs):
        args_ = [fix_bool(arg) for arg in args]
        kwargs_ = {k: fix_bool(v) for k,v in kwargs.iteritems()}
        return f(*args_, **kwargs_)

    return wrapper


def task(*args, **kwargs):
    """
    The fabric.decorators.task decorator which automatically converts command line task arguments
    to a boolean representation if applicable.
    :param args:
    :param kwargs:
    :return: wrapped
    """
    invoked = bool(not args or kwargs)
    task_class = kwargs.pop("task_class", tasks.WrappedCallableTask)

    def wrapper(f):
        return task_class(fix_boolean(f), *args, **kwargs)

    return wrapper if invoked else wrapper(args[0])

要点: https://gist.github.com/eltismerino/a8ec8584034c8a7d087e

于 2016-01-22T11:04:04.837 に答える
-3

fabric docsに記載されているように、すべての引数は文字列になります。ここで行う最も簡単なことは、引数をチェックすることです:

def myfunc(arg1, arg2):
  arg1 = (arg1 == 'True')

括弧は必須ではありませんが、読みやすくするために役立ちます。

編集:どうやら、以前の回答を実際に試していなかったようです。更新しました。(二年後。)

于 2012-07-25T04:15:59.303 に答える