如何通过PHP脚本调用Python程序并高效获取执行结果?
- 内容介绍
- 文章标签
- 相关推荐
本文共计2690个文字,预计阅读时间需要11分钟。
目录+前言+思路+代码+效果+补充+tf.app.run+前言+在设置中需要用到的+PHP+递归参数调用+Python+脚本并行获取后者的返回结果,经过查阅资料得以解决。+思路+PHP+借助shell_exec+通过类似的方式实现。
目录
- 前言
- 思路
- 代码
- 效果
- 补充
- tf.app.run
前言
在毕设中需要用到PHP传递参数调用Python脚本并获取后者返回的结果,经过查阅资料该问题得以解决。
思路
PHP借助shell_exec通过类似于python sum.py $aa $bb的形式以执行系统命令的方式传递参数给Python文件;
Python则通过sys.argv(需引入sys模块)来接收命令中所包含的参数(需要注意的是:此时传入的参数都会被默认为str类型,需要在函数内部进行解析和转换)并将处理结果通过print函数输出;
PHP通过将shell_exec函数返回的结果赋给变量实现取得Python返回数据的效果。
代码
PHP:
<form action="" method="post"> 请输入a:<input type="number" name="a" value="请输入a"><br> 请输入b: <input type="number" name="b" value="请输入b"> <button type="submit">计算</button> </form> <?php $aa = $_POST["a"]; $bb = $_POST["b"]; $cmd = shell_exec("python sum.py $aa $bb"); echo "a与b的和是: $cmd"; ?>
Python:
import sys a, b = sys.argv[1], sys.argv[2] # 接收位置参数 print(int(a)+int(b))
效果
补充
Python:
除了sys.argv,Python还可以通过argparse、tf.app.run获取传入参数。
相对于sys.argv,argparse和tf.app.run可以认为是基于参数名称的传入(前者是基于位置的参数传入)。
后者的具体使用方法记录如下:
argparse
示例1:
import argparse parser = argparse.ArgumentParser(description='manual to this script') parser.add_argument('--gpus', type=str, default = None) parser.add_argument('--batch-size', type=int, default=32) args = parser.parse_args() print args.gpus print args.batch_size
利用argparse模块,在函数内定义好相关的命名参数(包括名称、数据类型和默认值等),从而在命令行中可以方便的调用。
需要注意的是,脚本运行命令python script.py -gpus=0,1,2 --batch-size=10中的--batch-size会被自动解析成batch_size.parser.add_argument方法的type参数理论上可以是任何合法的类型, 但有些参数传入格式比较麻烦,例如list,所以一般使用bool,int,str,float这些基本类型就行了,更复杂的需求可以通过str传入,然后手动解析。bool类型的解析比较特殊,传入任何值都会被解析成True,传入空值时才为False
python script.py --bool-val=0 # args.bool_val=True python script.py --bool-val=False # args.bool_val=True python script.py --bool-val= # args.bool_val=什么都不写False
示例2:
Python:
import argparse parser = argparse.ArgumentParser(description='a demo of script') parser.add_argument('--a', type=float, default=0.0) # 添加变量 parser.add_argument('--b', type=float, default=1.0) if __name__ == '__main__': args = parser.parse_args() # 解析所有的命令行传入变量 add(args.a, args.b)
Shell:
python script.py --a=4.0 --b=3.0 # 另一种写法: python script.py --a 4.0 --b 3.0 # 返回结果7.0
总结:通过这个方法还能指定命令的帮助信息。具体请看API文档:docs.python.org/2/library/argparse.html
通过这个方法还能指定命令的帮助信息。具体请看API文档:docs.python.org/2/library/argparse.html
tf.app.run
tensorflow也提供了一种方便的解析方式。
脚本的执行命令为:
python script.py -gpus=0,1,2 --batch_size=10
对应的python代码为:
import tensorflow as tf tf.app.flags.DEFINE_string('gpus', None, 'gpus to use') tf.app.flags.DEFINE_integer('batch_size', 5, 'batch size') FLAGS = tf.app.flags.FLAGS def main(_): print FLAGS.gpus print FLAGS.batch_size if __name__=="__main__": tf.app.run()
有几点需要注意:
tensorflow只提供以下几种方法:
tf.app.flags.DEFINE_string,tf.app.flags.DEFINE_integer,tf.app.flags.DEFINE_boolean,
tf.app.flags.DEFINE_float四种方法,分别对应str,int,bool,float类型的参数。这里对bool的解析比较严格,传入1会被解析成True,其余任何值都会被解析成False。
脚本中需要定义一个接收一个参数的main方法:def main(_):,这个传入的参数是脚本名,一般用不到, 所以用下划线接收。
以batch_size参数为例,传入这个参数时使用的名称为--batch_size,也就是说,中划线不会像在argparse中一样被解析成下划线。
tf.app.run()会寻找并执行入口脚本的main方法。也只有在执行了tf.app.run()之后才能从FLAGS中取出参数。
从它的签名来看,它也是可以自己指定需要执行的方法的,不一定非得叫main:
run( main=None, argv=None )
tf.app.flags只是对argpars的简单封装。
代码:
# Copyright 2015 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Implementation of the flags interface.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import argparse as _argparse from tensorflow.python.util.all_util import remove_undocumented _global_parser = _argparse.ArgumentParser() # pylint: disable=invalid-name class _FlagValues(object): """Global container and accessor for flags and their values.""" def __init__(self): self.__dict__['__flags'] = {} self.__dict__['__parsed'] = False def _parse_flags(self, args=None): result, unparsed = _global_parser.parse_known_args(args=args) for flag_name, val in vars(result).items(): self.__dict__['__flags'][flag_name] = val self.__dict__['__parsed'] = True return unparsed def __getattr__(self, name): """Retrieves the 'value' attribute of the flag --name.""" if not self.__dict__['__parsed']: self._parse_flags() if name not in self.__dict__['__flags']: raise AttributeError(name) return self.__dict__['__flags'][name] def __setattr__(self, name, value): """Sets the 'value' attribute of the flag --name.""" if not self.__dict__['__parsed']: self._parse_flags() self.__dict__['__flags'][name] = value def _define_helper(flag_name, default_value, docstring, flagtype): """Registers 'flag_name' with 'default_value' and 'docstring'.""" _global_parser.add_argument('--' + flag_name, default=default_value, help=docstring, type=flagtype) # Provides the global object that can be used to access flags. FLAGS = _FlagValues() def DEFINE_string(flag_name, default_value, docstring): """Defines a flag of type 'string'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a string. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, str) def DEFINE_integer(flag_name, default_value, docstring): """Defines a flag of type 'int'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as an int. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, int) def DEFINE_boolean(flag_name, default_value, docstring): """Defines a flag of type 'boolean'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a boolean. docstring: A helpful message explaining the use of the flag. """ # Register a custom function for 'bool' so --flag=True works. def str2bool(v): return v.lower() in ('true', 't', '1') _global_parser.add_argument('--' + flag_name, nargs='?', const=True, help=docstring, default=default_value, type=str2bool) # Add negated version, stay consistent with argparse with regard to # dashes in flag names. _global_parser.add_argument('--no' + flag_name, action='store_false', dest=flag_name.replace('-', '_')) # The internal google library defines the following alias, so we match # the API for consistency. DEFINE_bool = DEFINE_boolean # pylint: disable=invalid-name def DEFINE_float(flag_name, default_value, docstring): """Defines a flag of type 'float'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a float. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, float) _allowed_symbols = [ # We rely on gflags documentation. 'DEFINE_bool', 'DEFINE_boolean', 'DEFINE_float', 'DEFINE_integer', 'DEFINE_string', 'FLAGS', ] remove_undocumented(__name__, _allowed_symbols)
PHP:
除了使用shell_exec(),还可以使用exec()、passthru()和system()函数调用系统命令,
它们四者的区别如下:
shell_exec()
通过shell环境执行命令,并且将完整的输出以字符串的方式返回。
也就是说,PHP先运行一个shell环境, 然后让shell进程运行你的命令, 并且把所有输出以字符串形式返回, 如果程序执行有错误或者程序没有任何输出, 则返回null.
exec()
string exec ( string $command [, array &$output [, int &$return_var ]] )与shell_exec()不一样,exec不会创建shell进程, 可以理解是php进程直接创建一个子进程, 运行指定的命令, 返回值只返回命令的最后一行, 所有的返回以参数形式返回, 上面的$output, 进程的退出代码以另外一个参数变量返回, 上面的$return_var
passthru()
void passthru ( string $command [, int &$return_var ] )与exec()类似, 唯一不同的是, 命令的所有输出返回内容都不再导入到PHP环境, 而是直接作为输出内容, 返回到浏览器的输出上, 等效是把所有返回内容直接echo输出.
system()
这个方法和passthru()类似, 但是system()方法会在程序的每行输出的时候执行一次缓存输出动作, 可以理解为, 只要外部程序输出一行,php就会马上把内容推送到浏览器, 无论这个内容是否足够大.php通常为了输出效率, 都会有一个输出缓存, 会等到输出内容足够大之后, 再一次输出返回.system()方法则强制输出内容立刻推送, 即使输出的内容只有一个字母. 如果客户端具有实时打印服务器的返回http内容流的能力, 就可以看到system()的实时推送效果.
到此这篇关于如何在PHP中调用Python并获取运行结果的文章就介绍到这了,更多相关PHP调用Python获取结果内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!
本文共计2690个文字,预计阅读时间需要11分钟。
目录+前言+思路+代码+效果+补充+tf.app.run+前言+在设置中需要用到的+PHP+递归参数调用+Python+脚本并行获取后者的返回结果,经过查阅资料得以解决。+思路+PHP+借助shell_exec+通过类似的方式实现。
目录
- 前言
- 思路
- 代码
- 效果
- 补充
- tf.app.run
前言
在毕设中需要用到PHP传递参数调用Python脚本并获取后者返回的结果,经过查阅资料该问题得以解决。
思路
PHP借助shell_exec通过类似于python sum.py $aa $bb的形式以执行系统命令的方式传递参数给Python文件;
Python则通过sys.argv(需引入sys模块)来接收命令中所包含的参数(需要注意的是:此时传入的参数都会被默认为str类型,需要在函数内部进行解析和转换)并将处理结果通过print函数输出;
PHP通过将shell_exec函数返回的结果赋给变量实现取得Python返回数据的效果。
代码
PHP:
<form action="" method="post"> 请输入a:<input type="number" name="a" value="请输入a"><br> 请输入b: <input type="number" name="b" value="请输入b"> <button type="submit">计算</button> </form> <?php $aa = $_POST["a"]; $bb = $_POST["b"]; $cmd = shell_exec("python sum.py $aa $bb"); echo "a与b的和是: $cmd"; ?>
Python:
import sys a, b = sys.argv[1], sys.argv[2] # 接收位置参数 print(int(a)+int(b))
效果
补充
Python:
除了sys.argv,Python还可以通过argparse、tf.app.run获取传入参数。
相对于sys.argv,argparse和tf.app.run可以认为是基于参数名称的传入(前者是基于位置的参数传入)。
后者的具体使用方法记录如下:
argparse
示例1:
import argparse parser = argparse.ArgumentParser(description='manual to this script') parser.add_argument('--gpus', type=str, default = None) parser.add_argument('--batch-size', type=int, default=32) args = parser.parse_args() print args.gpus print args.batch_size
利用argparse模块,在函数内定义好相关的命名参数(包括名称、数据类型和默认值等),从而在命令行中可以方便的调用。
需要注意的是,脚本运行命令python script.py -gpus=0,1,2 --batch-size=10中的--batch-size会被自动解析成batch_size.parser.add_argument方法的type参数理论上可以是任何合法的类型, 但有些参数传入格式比较麻烦,例如list,所以一般使用bool,int,str,float这些基本类型就行了,更复杂的需求可以通过str传入,然后手动解析。bool类型的解析比较特殊,传入任何值都会被解析成True,传入空值时才为False
python script.py --bool-val=0 # args.bool_val=True python script.py --bool-val=False # args.bool_val=True python script.py --bool-val= # args.bool_val=什么都不写False
示例2:
Python:
import argparse parser = argparse.ArgumentParser(description='a demo of script') parser.add_argument('--a', type=float, default=0.0) # 添加变量 parser.add_argument('--b', type=float, default=1.0) if __name__ == '__main__': args = parser.parse_args() # 解析所有的命令行传入变量 add(args.a, args.b)
Shell:
python script.py --a=4.0 --b=3.0 # 另一种写法: python script.py --a 4.0 --b 3.0 # 返回结果7.0
总结:通过这个方法还能指定命令的帮助信息。具体请看API文档:docs.python.org/2/library/argparse.html
通过这个方法还能指定命令的帮助信息。具体请看API文档:docs.python.org/2/library/argparse.html
tf.app.run
tensorflow也提供了一种方便的解析方式。
脚本的执行命令为:
python script.py -gpus=0,1,2 --batch_size=10
对应的python代码为:
import tensorflow as tf tf.app.flags.DEFINE_string('gpus', None, 'gpus to use') tf.app.flags.DEFINE_integer('batch_size', 5, 'batch size') FLAGS = tf.app.flags.FLAGS def main(_): print FLAGS.gpus print FLAGS.batch_size if __name__=="__main__": tf.app.run()
有几点需要注意:
tensorflow只提供以下几种方法:
tf.app.flags.DEFINE_string,tf.app.flags.DEFINE_integer,tf.app.flags.DEFINE_boolean,
tf.app.flags.DEFINE_float四种方法,分别对应str,int,bool,float类型的参数。这里对bool的解析比较严格,传入1会被解析成True,其余任何值都会被解析成False。
脚本中需要定义一个接收一个参数的main方法:def main(_):,这个传入的参数是脚本名,一般用不到, 所以用下划线接收。
以batch_size参数为例,传入这个参数时使用的名称为--batch_size,也就是说,中划线不会像在argparse中一样被解析成下划线。
tf.app.run()会寻找并执行入口脚本的main方法。也只有在执行了tf.app.run()之后才能从FLAGS中取出参数。
从它的签名来看,它也是可以自己指定需要执行的方法的,不一定非得叫main:
run( main=None, argv=None )
tf.app.flags只是对argpars的简单封装。
代码:
# Copyright 2015 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Implementation of the flags interface.""" from __future__ import absolute_import from __future__ import division from __future__ import print_function import argparse as _argparse from tensorflow.python.util.all_util import remove_undocumented _global_parser = _argparse.ArgumentParser() # pylint: disable=invalid-name class _FlagValues(object): """Global container and accessor for flags and their values.""" def __init__(self): self.__dict__['__flags'] = {} self.__dict__['__parsed'] = False def _parse_flags(self, args=None): result, unparsed = _global_parser.parse_known_args(args=args) for flag_name, val in vars(result).items(): self.__dict__['__flags'][flag_name] = val self.__dict__['__parsed'] = True return unparsed def __getattr__(self, name): """Retrieves the 'value' attribute of the flag --name.""" if not self.__dict__['__parsed']: self._parse_flags() if name not in self.__dict__['__flags']: raise AttributeError(name) return self.__dict__['__flags'][name] def __setattr__(self, name, value): """Sets the 'value' attribute of the flag --name.""" if not self.__dict__['__parsed']: self._parse_flags() self.__dict__['__flags'][name] = value def _define_helper(flag_name, default_value, docstring, flagtype): """Registers 'flag_name' with 'default_value' and 'docstring'.""" _global_parser.add_argument('--' + flag_name, default=default_value, help=docstring, type=flagtype) # Provides the global object that can be used to access flags. FLAGS = _FlagValues() def DEFINE_string(flag_name, default_value, docstring): """Defines a flag of type 'string'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a string. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, str) def DEFINE_integer(flag_name, default_value, docstring): """Defines a flag of type 'int'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as an int. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, int) def DEFINE_boolean(flag_name, default_value, docstring): """Defines a flag of type 'boolean'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a boolean. docstring: A helpful message explaining the use of the flag. """ # Register a custom function for 'bool' so --flag=True works. def str2bool(v): return v.lower() in ('true', 't', '1') _global_parser.add_argument('--' + flag_name, nargs='?', const=True, help=docstring, default=default_value, type=str2bool) # Add negated version, stay consistent with argparse with regard to # dashes in flag names. _global_parser.add_argument('--no' + flag_name, action='store_false', dest=flag_name.replace('-', '_')) # The internal google library defines the following alias, so we match # the API for consistency. DEFINE_bool = DEFINE_boolean # pylint: disable=invalid-name def DEFINE_float(flag_name, default_value, docstring): """Defines a flag of type 'float'. Args: flag_name: The name of the flag as a string. default_value: The default value the flag should take as a float. docstring: A helpful message explaining the use of the flag. """ _define_helper(flag_name, default_value, docstring, float) _allowed_symbols = [ # We rely on gflags documentation. 'DEFINE_bool', 'DEFINE_boolean', 'DEFINE_float', 'DEFINE_integer', 'DEFINE_string', 'FLAGS', ] remove_undocumented(__name__, _allowed_symbols)
PHP:
除了使用shell_exec(),还可以使用exec()、passthru()和system()函数调用系统命令,
它们四者的区别如下:
shell_exec()
通过shell环境执行命令,并且将完整的输出以字符串的方式返回。
也就是说,PHP先运行一个shell环境, 然后让shell进程运行你的命令, 并且把所有输出以字符串形式返回, 如果程序执行有错误或者程序没有任何输出, 则返回null.
exec()
string exec ( string $command [, array &$output [, int &$return_var ]] )与shell_exec()不一样,exec不会创建shell进程, 可以理解是php进程直接创建一个子进程, 运行指定的命令, 返回值只返回命令的最后一行, 所有的返回以参数形式返回, 上面的$output, 进程的退出代码以另外一个参数变量返回, 上面的$return_var
passthru()
void passthru ( string $command [, int &$return_var ] )与exec()类似, 唯一不同的是, 命令的所有输出返回内容都不再导入到PHP环境, 而是直接作为输出内容, 返回到浏览器的输出上, 等效是把所有返回内容直接echo输出.
system()
这个方法和passthru()类似, 但是system()方法会在程序的每行输出的时候执行一次缓存输出动作, 可以理解为, 只要外部程序输出一行,php就会马上把内容推送到浏览器, 无论这个内容是否足够大.php通常为了输出效率, 都会有一个输出缓存, 会等到输出内容足够大之后, 再一次输出返回.system()方法则强制输出内容立刻推送, 即使输出的内容只有一个字母. 如果客户端具有实时打印服务器的返回http内容流的能力, 就可以看到system()的实时推送效果.
到此这篇关于如何在PHP中调用Python并获取运行结果的文章就介绍到这了,更多相关PHP调用Python获取结果内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

