如何在PHP中調用Python并獲取運行結果
前言
在畢設中需要用到PHP
傳遞參數調用Python
腳本并獲取后者返回的結果,經過查閱資料該問題得以解決。
思路
PHP
借助shell_exec
通過類似于python sum.py $aa $bb
的形式以執(zhí)行系統命令的方式傳遞參數給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
文檔:https://docs.python.org/2/library/argparse.html
通過這個方法還能指定命令的幫助信息。具體請看API
文檔:https://docs.python.org/2/library/argparse.html
tf.app.run
tensorflow
也提供了一種方便的解析方式。
腳本的執(zhí)行命令為:
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()
會尋找并執(zhí)行入口腳本的main
方法。也只有在執(zhí)行了tf.app.run()
之后才能從FLAGS
中取出參數。
從它的簽名來看,它也是可以自己指定需要執(zhí)行的方法的,不一定非得叫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 # # http://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()
函數調用系統命令,
它們四者的區(qū)別如下:
shell_exec()
通過 shell
環(huán)境執(zhí)行命令,并且將完整的輸出以字符串的方式返回。
也就是說, PHP
先運行一個shell
環(huán)境, 然后讓shell
進程運行你的命令, 并且把所有輸出以字符串形式返回, 如果程序執(zhí)行有錯誤或者程序沒有任何輸出, 則返回null
.
exec()
string exec ( string $command [, array &$output [, int &$return_var ]] )
與 shell_exec()
不一樣, exec
不會創(chuàng)建shell
進程, 可以理解是php
進程直接創(chuàng)建一個子進程, 運行指定的命令, 返回值只返回命令的最后一行, 所有的返回以參數形式返回, 上面的 $output
, 進程的退出代碼以另外一個參數變量返回, 上面的 $return_var
passthru()
void passthru ( string $command [, int &$return_var ] )
與 exec()
類似, 唯一不同的是, 命令的所有輸出返回內容都不再導入到 PHP
環(huán)境, 而是直接作為輸出內容, 返回到瀏覽器的輸出上, 等效是把所有返回內容直接 echo
輸出.
system()
這個方法和 passthru()
類似, 但是 system()
方法會在程序的每行輸出的時候執(zhí)行一次緩存輸出動作, 可以理解為, 只要外部程序輸出一行, php
就會馬上把內容推送到瀏覽器, 無論這個內容是否足夠大. php
通常為了輸出效率, 都會有一個輸出緩存, 會等到輸出內容足夠大之后, 再一次輸出返回. system()
方法則強制輸出內容立刻推送, 即使輸出的內容只有一個字母. 如果客戶端具有實時打印服務器的返回 http
內容流的能力, 就可以看到 system()
的實時推送效果.
到此這篇關于如何在PHP中調用Python并獲取運行結果的文章就介紹到這了,更多相關PHP調用Python獲取結果內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
php讀取二進制流(C語言結構體struct數據文件)的深入解析
本篇文章是對php讀取二進制流(C語言結構體struct數據文件)進行了詳細的分析介紹,需要的朋友參考下2013-06-06