传递参数的技巧

来源:互联网 发布:手机淘宝怎么没有社区 编辑:程序博客网 时间:2024/06/06 07:52

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


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

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

编写 最基本的命令委托:


@taskdef 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_hostdef 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 --listCreated on 2017-10-11@author: laok@ArgusTech@email:  1306743659@qq.com@copyright: Apache License, Version 2.0Available 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的模板工具,可以灵活处理 远程运维问题。









原创粉丝点击