使用参数调用 python 函数并在 autohotkey 中获取返回值

Call python function with arguments and get returned value in autohotkey

我有一个名为 "server.py" 的 python 脚本,在其中我有一个函数 def calcFunction(arg1): ... return output 如何调用带参数的函数 calcFunction 并使用 return 值在自动热键?这就是我想在 autohotkey 中做的事情:

ToSend = someString ; a string
output = Run server.py, calcFunction(ToSend) ; get the returned value from the function with ToSend as argument
Send, output ; use the returned value in autohotkey

我在网上看过,但似乎没有什么能完全回答我的问题。甚至可以做到吗?

为了将您的参数发送到 Python,您可以使用 Python 脚本中的参数。您可以使用 sys 库执行此操作:

import sys
print(sys.argv[0]) # name of file
print(sys.argv[1]) # first argument
print(sys.argv[2]) # second argument...

在您的 AutoHotKey 脚本中,您可以将参数发送到 Python 脚本,方法是在指定文件名后立即将它们添加为参数:

RunWait, server.py "This will be printed as the first argument!" "This is the second!"

然后,要将函数的输出返回给 AHK,您可以利用它的 exit() 函数再次使用 sys

sys.exit(EXIT_NUMBER)

然后回到 AHK,您会收到变量 ErrorLevel 中的 EXIT_NUMBER。 综上所述,您的代码应如下所示:

; AHK
RunWait, server.py "%ToSend%"

# Python
sys.exit(calcFunction(sys.argv[1]))

; AHK
MsgBox %ErrorLevel%

使用python COM 服务器,ahk 真的可以调用python 函数。直接。
你这样使用它:MsgBox % pythonComServer.toUppercase("hello world")

简单示例:return大写字符串
使用 中的 python 部分并将其用于 ahk 部分:

调用 python 函数 uppercase.ahk

#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#KeyHistory 0
ListLines Off

pythonComServer:=ComObjCreate("Python.stringUppercaser")
;or
; pythonComServer:=ComObjCreate("{C70F3BF7-2947-4F87-B31E-9F5B8B13D24F}") ;use your own CLSID

MsgBox % pythonComServer.toUppercase("hello world")
Exitapp

f3::Exitapp

定制版:(数学)使用SymPy简化表达式
首先阅读此内容以了解:

sympy com server.py

from sympy import simplify, Number, N
from sympy.parsing.sympy_parser import standard_transformations, implicit_multiplication_application, convert_xor
from sympy.parsing.sympy_parser import parse_expr

from decimal import Decimal

from winsound import MessageBeep

transformations = standard_transformations + (implicit_multiplication_application, convert_xor)

def removeTrailingZerosFromNum(num):
    dec = Decimal(str(num))

    tup = dec.as_tuple()
    delta = len(tup.digits) + tup.exponent
    digits = ''.join(str(d) for d in tup.digits)
    if delta <= 0:
        zeros = abs(tup.exponent) - len(tup.digits)
        val = '0.' + ('0' * zeros) + digits
    else:
        val = digits[:delta] + ('0' * tup.exponent) + '.' + digits[delta:]
    val = val.rstrip('0')
    if val[-1] == '.':
        val = val[:-1]
    if tup.sign:
        return '-' + val
    return val


def removeTrailingZerosFromExpr(operatorObject):
    if operatorObject.args:
        return type(operatorObject)(*[removeTrailingZerosFromExpr(i) for i in operatorObject.args])
    else:
        try:
            return Number(removeTrailingZerosFromNum(operatorObject))
        except:
            return operatorObject

def removeTrailingZerosFromExprOrNumber(operatorObject):
    try:
        return removeTrailingZerosFromNum(operatorObject)
    except:
        return removeTrailingZerosFromExpr(operatorObject)

class BasicServer:
    # list of all method names exposed to COM
    _public_methods_ = ["parExprN"]

    @staticmethod
    def parExprN(clipBak):
        parsed = parse_expr(clipBak, transformations=transformations)
        simplified = simplify(N(parsed))
        finalStr = str(removeTrailingZerosFromExprOrNumber(simplified))
        MessageBeep(-1)
        return finalStr.replace("**", "^")

if __name__ == "__main__":
    import sys

    if len(sys.argv) < 2:
        print("Error: need to supply arg (""--register"" or ""--unregister"")")
        sys.exit(1)
    else:
        import win32com.server.register
        import win32com.server.exception

        # this server's CLSID
        # NEVER copy the following ID 
        # Use "print(pythoncom.CreateGuid())" to make a new one.
        myClsid="{4530C817-6C66-46C8-8FB0-E606970A8DF6}"
        # this server's (user-friendly) program ID, can be anything you want
        myProgID="Python.SimplifyExpr"
        
        import ctypes
        def make_sure_is_admin():
            try:
                if ctypes.windll.shell32.IsUserAnAdmin():
                    return
            except:
                pass
            exit("YOU MUST RUN THIS AS ADMIN")

        if sys.argv[1] == "--register":
            make_sure_is_admin()

            import pythoncom
            import os.path
            realPath = os.path.realpath(__file__)
            dirName = os.path.dirname(realPath)
            nameOfThisFile = os.path.basename(realPath)
            nameNoExt = os.path.splitext(nameOfThisFile)[0]
            # stuff will be written here
            # HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID${myClsid}
            # HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{c2467d33-71c5-4057-977c-e847c2286882}
            # and here
            # HKEY_LOCAL_MACHINE\SOFTWARE\Classes${myProgID}
            # HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Python.SimplifyExpr
            win32com.server.register.RegisterServer(
                clsid=myClsid,
                # I guess this is {fileNameNoExt}.{className}
                pythonInstString=nameNoExt + ".BasicServer", #sympy com server.BasicServer
                progID=myProgID,
                # optional description
                desc="(math) SymPy simplify Expression",
                #we only want the registry key LocalServer32
                #we DO NOT WANT InProcServer32: pythoncom39.dll, NO NO NO
                clsctx=pythoncom.CLSCTX_LOCAL_SERVER,
                #this is needed if this file isn't in PYTHONPATH: it tells regedit which directory this file is located
                #this will write HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{4530C817-6C66-46C8-8FB0-E606970A8DF6}\PythonCOMPath : dirName
                addnPath=dirName,
            )
            print("Registered COM server.")
            # don't use UseCommandLine(), as it will write InProcServer32: pythoncom39.dll
            # win32com.server.register.UseCommandLine(BasicServer)
        elif sys.argv[1] == "--unregister":
            make_sure_is_admin()

            print("Starting to unregister...")

            win32com.server.register.UnregisterServer(myClsid, myProgID)

            print("Unregistered COM server.")
        else:
            print("Error: arg not recognized")

注册:
python "sympy com server.py" --register


同情 com client.ahk

#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance, force
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#KeyHistory 0
ListLines Off

sympyComServer:=ComObjCreate("Python.SimplifyExpr")
;or
; pythonComServer:=ComObjCreate("{4530C817-6C66-46C8-8FB0-E606970A8DF6}") ;use your own CLSID

; clipboard:=sympyComServer.parExprN("1+3*7")
clipboard:=sympyComServer.parExprN("1/3 + 1/2")

$#s::
clipboard:=sympyComServer.parExprN(clipboard)
return

f3::Exitapp