传递参数的技巧

python灵活的语法和动态机制,给了写代码的太多 奇技淫巧.


有时候需要包装一个函数,然而函数的参数太多,如果一一赋值,就太罗嗦。

可以考虑使用 locals()或者 从 frame里面提取 各种信息 比如 f_locals/f_globals等等

编写 最基本的命令委托:


@task
def sudo_(command, shell=True, pty=True, combine_stderr=None, user=None,
          quiet=False, warn_only=False, 
          stdout=None, stderr=None, group=None,
          timeout=None, shell_escape=None, capture_buffer_size=None):
    return sudo(**locals())

这样就可以利用 locals()搜集的变量,传递给 sudo原来的函数。


sudo库代码是这样写的:

@needs_host
def sudo(command, shell=True, pty=True, combine_stderr=None, user=None,
    quiet=False, warn_only=False, stdout=None, stderr=None, group=None,
    timeout=None, shell_escape=None, capture_buffer_size=None):
    """
    Run a shell command on a remote host, with superuser privileges.

    `sudo` is identical in every way to `run`, except that it will always wrap
    the given ``command`` in a call to the ``sudo`` program to provide
    superuser privileges.

    `sudo` accepts additional ``user`` and ``group`` arguments, which are
    passed to ``sudo`` and allow you to run as some user and/or group other
    than root.  On most systems, the ``sudo`` program can take a string
    username/group or an integer userid/groupid (uid/gid); ``user`` and
    ``group`` may likewise be strings or integers.

    You may set :ref:`env.sudo_user <sudo_user>` at module level or via
    `~fabric.context_managers.settings` if you want multiple ``sudo`` calls to
    have the same ``user`` value. An explicit ``user`` argument will, of
    course, override this global setting.

    Examples::

        sudo("~/install_script.py")
        sudo("mkdir /var/www/new_docroot", user="www-data")
        sudo("ls /home/jdoe", user=1001)
        result = sudo("ls /tmp/")
        with settings(sudo_user='mysql'):
            sudo("whoami") # prints 'mysql'

    .. versionchanged:: 1.0
        See the changed and added notes for `~fabric.operations.run`.

    .. versionchanged:: 1.5
        Now honors :ref:`env.sudo_user <sudo_user>`.

    .. versionadded:: 1.5
        The ``quiet``, ``warn_only``, ``stdout`` and ``stderr`` kwargs.

    .. versionadded:: 1.5
        The return value attributes ``.command`` and ``.real_command``.

    .. versionadded:: 1.7
        The ``shell_escape`` argument.

    .. versionadded:: 1.11
        The ``capture_buffer_size`` argument.
    """
    return _run_command(
        command, shell, pty, combine_stderr, sudo=True,
        user=user if user else env.sudo_user,
        group=group, quiet=quiet, warn_only=warn_only, stdout=stdout,
        stderr=stderr, timeout=timeout, shell_escape=shell_escape,
        capture_buffer_size=capture_buffer_size,
    )

参数一个一个传递,显得稍微罗嗦点了。


1>补充: 如果定义了局部变量,就可以考虑 使用 pop不需要的参数,委托给 原来的函数。

2>对于 *args,**kwargs,就不能使用 这种 技巧了。

这种技巧省了很多代码。


目前我可以在 fabric里面直接导入原始命令:

Cmd:fab --list-format=normal --list

Created on 2017-10-11

@author: laok@ArgusTech
@email:  [email protected]
@copyright: Apache License, Version 2.0

Available commands:

    fabric_tasks.get_
    fabric_tasks.local_
    fabric_tasks.open_shell_
    fabric_tasks.prompt_
    fabric_tasks.put_
    fabric_tasks.reboot_
    fabric_tasks.require_
    fabric_tasks.run_
    fabric_tasks.sudo_


Cmd:fab --show=error --timeout=10 --abort-on-prompts --colorize-errors fabric_tasks.run_:command=python /home/kliu/proj/celery_cmd_worker_restart.py
[kliu@xxx] Executing task 'fabric_tasks.run_'
[kliu@xxx] run: python /home/kliu/proj/celery_cmd_worker_restart.py
[kliu@xxx] out: Cmd:celery multi restart w1 --app=celery_proj --autoscale=10,2 --hostname=laok-1.%h -O fair --heartbeat-interval=5 --workdir=/home/kliu/proj --loglevel=info --queues=laok --autoreload --detach --discard --no-color --events
[kliu@xxx] out: celery multi v3.1.18 (Cipater)
[kliu@xxx] out: > Stopping nodes...
[kliu@xxx] out: 	> w1@laok-1.%h: TERM -> 10620
[kliu@xxx] out: > Waiting for 1 node -> 10620.....
[kliu@xxx] out: 	> w1@laok-1.%h: OK
[kliu@xxx] out: > Restarting node w1@laok-1.%h: OK


通过 locals()解决了 一一参数传递问题。

制作了 celery-task的模板工具,可以灵活处理 远程运维问题。









猜你喜欢

转载自blog.csdn.net/laoki/article/details/78227366
今日推荐