无法将FontForge作为自定义Python脚本中的模块导入

bpsygsoo  于 2023-03-20  发布在  Python
关注(0)|答案(1)|浏览(250)

我有以下脚本:

import fontforge
import os.path
import sys

if len(sys.argv) < 3:
    print("Usage: [FONT] [OUTPUTDIR]")
    exit(1)

fontpath = sys.argv[1]
font     = fontforge.open(fontpath)
outdir   = sys.argv[2]

if os.path.exists(outdir):
    pass
elif os.access(os.path.dirname(outdir), os.W_OK):
    os.makedirs(outdir)
else:
    exit(1)

for name in font:
    filename = name + ".svg"
    outfull = os.path.join(outdir,filename)
    font[name].export(outfull)

脚本将所有glyphs转储到文件夹中的各个SVG文件。
不管怎样,我已经安装了最新的Windows版本的FontForge。
据我所知,FontForge嵌入了python,二进制代码是ffpython.exe,所以应该可以调用ffpython myscript.py {arg1 arg2 arg3}
问题是这行不通。
当我执行ffpython myscript.py arg1 arg2时,我得到一个错误:
ImportError: DLL load failed while importing fontforge: The specified procedure could not be found.
调用ffpython,然后直接在解释器中键入import fontforge,也可能导致相同的错误。
FontForge附带的批处理文件位于C:\Program Files (x86)\FontForgeBuilds\fontforge-console.bat
如果我运行这个批处理文件,它会设置一些变量,然后打开一个控制台窗口,如果我 then 在那个控制台窗口调用ffpython并输入import fontforge,所有的事情都会像预期的那样神奇地工作。
但这是一个非常有限和不恰当的解决方案,我不想每次运行与FontForge接口的Python脚本时都必须打开这个神奇的批处理文件。
所以我的问题是:
如何将FontForge作为Python中的一个模块正确安装?如何获得一个python脚本来导入通过ffpython运行的fontforge模块?
我将非常感激任何帮助。

编辑:

通过@CristiFati从管理PowerShell提示符运行测试脚本,其中PWD与ffpython不同(失败):

03-14 20:06:09 D:\> & 'C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe' .\code00.py
Executable: C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit]
CWD: D:\
UName: None
PATH: C:\Program Files\PowerShell\7;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\libnvvp;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\bin\Intel64;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\compiler;C:\Python\Python310\Scripts\;C:\Python\Python310\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\BIN;C:\Program Files\Git\cmd;C:\Program Files\GitHub CLI\;C:\Program Files\7-Zip;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.1.1;C:\Program Files\dotnet\;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\PowerShell\7\;C:\Program Files (x86)\FontForgeBuilds\bin;C:\Users\myusername\AppData\Local\Microsoft\WindowsApps;C:\Users\myusername\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\myusername\.dotnet\tools;C:\Program Files (x86)\FontForgeBuilds\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python310.zip', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\lib-dynload', 'D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages']
Traceback (most recent call last):
  File "D:\code00.py", line 12, in <module>
    import fontforge as ff
ImportError: DLL load failed while importing fontforge: The specified procedure could not be found.
03-14 20:06:24 D:\>

如果我使用CMD,会出现相同的结果。
通过@CristiFati从管理PowerShell提示符运行测试脚本,其中PWD为C:\Program Files (x86)\FontForgeBuilds\bin(成功):

03-14 20:16:08 C:\Program Files (x86)\FontForgeBuilds\bin> ffpython D:\code00.py
Executable: C:\Program Files (x86)\FontForgeBuilds\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit]
CWD: C:\Program Files (x86)\FontForgeBuilds\bin
UName: None
PATH: C:\Program Files\PowerShell\7;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.0\libnvvp;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Files\cpp\bin\Intel64;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\intel64_win\compiler;C:\Program Files (x86)\Common Files\Intel\Shared Libraries\redist\ia32_win\compiler;C:\Python\Python310\Scripts\;C:\Python\Python310\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\BIN;C:\Program Files\Git\cmd;C:\Program Files\GitHub CLI\;C:\Program Files\7-Zip;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.1.1;C:\Program Files\dotnet\;C:\Program Files\CMake\bin;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\PowerShell\7\;C:\Program Files (x86)\FontForgeBuilds\bin;C:\Users\myusername\AppData\Local\Microsoft\WindowsApps;C:\Users\myusername\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\myusername\.dotnet\tools;C:\Program Files (x86)\FontForgeBuilds\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['D:\\', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python310.zip', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\lib-dynload', 'C:\\Program Files (x86)\\FontForgeBuilds\\bin', 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages']
Python 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit] 032bit on win32

<module 'fontforge' from 'C:\\Program Files (x86)\\FontForgeBuilds\\lib\\python3.10\\site-packages\\fontforge.pyd'>
['SpiroVersion', 'UnicodeAnnotationFromLib', 'UnicodeBlockCountFromLib', 'UnicodeBlockEndFromLib', 'UnicodeBlockNameFromLib', 'UnicodeBlockStartFromLib', 'UnicodeNameFromLib', 'UnicodeNames2FromLib', 'UnicodeNamesListVersion', '__date__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'activeFont', 'activeFontInUI', 'activeGlyph', 'activeLayer', 'ask', 'askChoices', 'askMulti', 'askString', 'awcontext', 'awglyph', 'configurePlugins', 'contour', 'cvt', 'defaultOtherSubrs', 'font', 'fonts', 'fontsInFile', 'getConvexNib', 'getPluginInfo', 'getPrefs', 'glyph', 'glyphPen', 'hasSpiro', 'hasUserInterface', 'hooks', 'layer', 'layer_array', 'layerinfo', 'layerinfo_array', 'loadEncodingFile', 'loadNamelist', 'loadNamelistDir', 'loadPlugins', 'loadPrefs', 'logWarning', 'math', 'mathKern', 'nameFromUnicode', 'onAppClosing', 'open', 'openFilename', 'parseTTInstrs', 'point', 'postError', 'postNotice', 'preloadCidmap', 'printSetup', 'private', 'readOtherSubrsFile', 'references', 'registerGlyphSeparationHook', 'registerImportExport', 'registerMenuItem', 'runInitScripts', 'saveFilename', 'savePrefs', 'scriptFromUnicode', 'scriptPath', 'selection', 'setConvexNib', 'setPrefs', 'spiroCorner', 'spiroG2', 'spiroG4', 'spiroLeft', 'spiroOpen', 'spiroRight', 'splineCorner', 'splineCurve', 'splineHVCurve', 'splineTangent', 'unParseTTInstrs', 'unicodeFromName', 'unitShape', 'unspecifiedMathValue', 'userConfigPath', 'version']

Done.

所以我需要弄清楚为什么只有当我的PWD是C:\Program Files (x86)\FontForgeBuilds\bin时才能正常工作,我不明白为什么它不能正常工作。

iezvtpos

iezvtpos1#

刚刚安装了 FontForge 20230101。使用以下测试脚本。

  • 代码00.py *:
#!/usr/bin/env python

import os
import sys

print("Executable:", sys.executable)
print("Version:", sys.version)
print("CWD:", os.getcwd())
print("UName:", getattr(os, "uname", lambda: None)())
for evn in ("PATH", "PYTHONHOME", "PYTHONPATH"):
    print("{:s}: {:}".format(evn, os.environ.get(evn)))
print("sys.path:", sys.path)

import fontforge as ff

def main(*argv):
    print(ff)
    print(dir(ff))

if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

输出

[cfati@CFATI-W10PC064:e:\Work\Dev\StackExchange\StackOverflow\q073506592]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> :: Run FFPython (full path)
[prompt]> "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" ./code00.py
Python 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit] 032bit on win32

Executable: c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit]
CWD: E:\Work\Dev\StackExchange\StackOverflow\q073506592
UName: None
PATH: C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['e:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python310.zip', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\lib-dynload', 'E:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\site-packages']
<module 'fontforge' from 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\site-packages\\fontforge.pyd'>
['SpiroVersion', 'UnicodeAnnotationFromLib', 'UnicodeBlockCountFromLib', 'UnicodeBlockEndFromLib', 'UnicodeBlockNameFromLib', 'UnicodeBlockStartFromLib', 'UnicodeNameFromLib', 'UnicodeNames2FromLib', 'UnicodeNamesListVersion', '__date__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'activeFont', 'activeFontInUI', 'activeGlyph', 'activeLayer', 'ask', 'askChoices', 'askMulti', 'askString', 'awcontext', 'awglyph', 'configurePlugins', 'contour', 'cvt', 'defaultOtherSubrs', 'font', 'fonts', 'fontsInFile', 'getConvexNib', 'getPluginInfo', 'getPrefs', 'glyph', 'glyphPen', 'hasSpiro', 'hasUserInterface', 'hooks', 'layer', 'layer_array', 'layerinfo', 'layerinfo_array', 'loadEncodingFile', 'loadNamelist', 'loadNamelistDir', 'loadPlugins', 'loadPrefs', 'logWarning', 'math', 'mathKern', 'nameFromUnicode', 'onAppClosing', 'open', 'openFilename', 'parseTTInstrs', 'point', 'postError', 'postNotice', 'preloadCidmap', 'printSetup', 'private', 'readOtherSubrsFile', 'references', '
registerGlyphSeparationHook', 'registerImportExport', 'registerMenuItem', 'runInitScripts', 'saveFilename', 'savePrefs', 'scriptFromUnicode', 'scriptPath', 'selection', 'setConvexNib', 'setPrefs', 'spiroCorner', 'spiroG2', 'spiroG4', 'spiroLeft', 'spiroOpen', 'spiroRight', 'splineCorner', 'splineCurve', 'splineHVCurve', 'splineTangent', 'unParseTTInstrs', 'unicodeFromName', 'unitShape', 'unspecifiedMathValue', 'userConfigPath', 'version']

Done.

[prompt]>
[prompt]> :: More tests (paths related)
[prompt]> set _PATH=%PATH%

[prompt]> set PATH=%_PATH%;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin

[prompt]> :: Run FFPython (from PATH). Suppress stdout
[prompt]> ffpython.exe ./code00.py > nul

[prompt]>
[prompt]> :: Check module
[prompt]> "c:\Install\pc064\LucasG\DependenciesWalkerPolitistTexan\Version\DependenciesGui.exe" "c:\Install\pc032\FontForge\FontForgeBuilds\Version\lib\python3.10\site-packages\fontforge.pyd"

[prompt]> :: Dependencies window pops up

以及(扩展)模块 * 依赖项 *([GitHub]: lucasg/Dependencies)窗口:

显然,一切正常,唯一合乎逻辑的结论是,你的环境一团糟。
然后我注意到一个“小”细节:您使用的是虚拟环境

输出(另一个(Cmd)端子):

[cfati@CFATI-W10PC064:e:\Work\Dev\StackExchange\StackOverflow\q073506592]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> :: Create VEnv (from FFPython)
[prompt]> "c:\Install\pc064\Python\Python\03.10\python.exe" -m virtualenv -p "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" "c:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0"
created virtual environment CPython3.10.9.final.0-32 in 843ms
  creator CPython3Windows(dest=C:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\cfati\AppData\Local\pypa\virtualenv)
    added seed packages: pip==23.0.1, setuptools==67.4.0, wheel==0.38.4
  activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

[prompt]> "c:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0\bin\activate.bat"

(py_pc032_03.10_test1ff0) [prompt]>
(py_pc032_03.10_test1ff0) [prompt]> :: Various tests
(py_pc032_03.10_test1ff0) [prompt]> "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" ./code00.py > nul

(py_pc032_03.10_test1ff0) [prompt]> set _PATH=%PATH%

(py_pc032_03.10_test1ff0) [prompt]> set PATH=%_PATH%;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin

(py_pc032_03.10_test1ff0) [prompt]>
(py_pc032_03.10_test1ff0) [prompt]> ffpython ./code00.py > nul

(py_pc032_03.10_test1ff0) [prompt]> python ./code00.py > nul
Traceback (most recent call last):
  File "e:\Work\Dev\StackExchange\StackOverflow\q073506592\code00.py", line 14, in <module>
    import fontforge as ff
ModuleNotFoundError: No module named 'fontforge'

(py_pc032_03.10_test1ff0) [prompt]>
(py_pc032_03.10_test1ff0) [prompt]> :: View differences
(py_pc032_03.10_test1ff0) [prompt]> ffpython ./code00.py
Executable: C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit]
CWD: E:\Work\Dev\StackExchange\StackOverflow\q073506592
UName: None
PATH: C:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0\bin;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['e:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python310.zip', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\lib-dynload', 'E:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\site-packages']
Python 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit] 032bit on win32

<module 'fontforge' from 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\site-packages\\fontforge.pyd'>
['SpiroVersion', 'UnicodeAnnotationFromLib', 'UnicodeBlockCountFromLib', 'UnicodeBlockEndFromLib', 'UnicodeBlockNameFromLib', 'UnicodeBlockStartFromLib', 'UnicodeNameFromLib', 'UnicodeNames2FromLib', 'UnicodeNamesListVersion', '__date__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', 'activeFont', 'activeFontInUI', 'activeGlyph', 'activeLayer', 'ask', 'askChoices', 'askMulti', 'askString', 'awcontext', 'awglyph', 'configurePlugins', 'contour', 'cvt', 'defaultOtherSubrs', 'font', 'fonts', 'fontsInFile', 'getConvexNib', 'getPluginInfo', 'getPrefs', 'glyph', 'glyphPen', 'hasSpiro', 'hasUserInterface', 'hooks', 'layer', 'layer_array', 'layerinfo', 'layerinfo_array', 'loadEncodingFile', 'loadNamelist', 'loadNamelistDir', 'loadPlugins', 'loadPrefs', 'logWarning', 'math', 'mathKern', 'nameFromUnicode', 'onAppClosing', 'open', 'openFilename', 'parseTTInstrs', 'point', 'postError', 'postNotice', 'preloadCidmap', 'printSetup', 'private', 'readOtherSubrsFile', 'references', '
registerGlyphSeparationHook', 'registerImportExport', 'registerMenuItem', 'runInitScripts', 'saveFilename', 'savePrefs', 'scriptFromUnicode', 'scriptPath', 'selection', 'setConvexNib', 'setPrefs', 'spiroCorner', 'spiroG2', 'spiroG4', 'spiroLeft', 'spiroOpen', 'spiroRight', 'splineCorner', 'splineCurve', 'splineHVCurve', 'splineTangent', 'unParseTTInstrs', 'unicodeFromName', 'unitShape', 'unspecifiedMathValue', 'userConfigPath', 'version']

Done.

(py_pc032_03.10_test1ff0) [prompt]>
(py_pc032_03.10_test1ff0) [prompt]> python ./code00.py
Executable: C:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0\bin\python.exe
Version: 3.10.9 (main, Dec 10 2022, 09:16:22)  [GCC 12.2.0 32 bit]
CWD: E:\Work\Dev\StackExchange\StackOverflow\q073506592
UName: None
PATH: C:\Work\Dev\VEnvs\py_pc032_03.10_test1ff0\bin;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.08.07_test0\Scripts;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\
PYTHONHOME: None
PYTHONPATH: None
sys.path: ['e:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python310.zip', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10', 'C:\\Install\\pc032\\FontForge\\FontForgeBuilds\\Version\\lib\\python3.10\\lib-dynload', 'E:\\Work\\Dev\\StackExchange\\StackOverflow\\q073506592', 'C:\\Work\\Dev\\VEnvs\\py_pc032_03.10_test1ff0\\lib\\python3.10\\site-packages']
Traceback (most recent call last):
  File "e:\Work\Dev\StackExchange\StackOverflow\q073506592\code00.py", line 14, in <module>
    import fontforge as ff
ModuleNotFoundError: No module named 'fontforge'

查看 sys.path 的最后一个条目(在两种情况下),就会明白为什么会发生这种情况。
因此,这是一个与虚拟环境相关的问题。更准确地说,这是一个虚拟环境访问 Python 示例(系统)的 site-packages 目录的问题。
为了解决这个问题,在创建虚拟环境时,传递 --system-site-packages 标记,如中所述:

(py_pc032_03.10_test1ff0) [prompt]> deactivate
[prompt]>
[prompt]> :: Create VEnv (from FFPython) - WITH --system-site-packages
[prompt]> "c:\Install\pc064\Python\Python\03.10\python.exe" -m virtualenv -p "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" --system-site-packages "c:\Work\Dev\VEnvs\py_pc032_03.10_test1ff1"
created virtual environment CPython3.10.9.final.0-32 in 859ms
  creator CPython3Windows(dest=C:\Work\Dev\VEnvs\py_pc032_03.10_test1ff1, clear=False, no_vcs_ignore=False, global=True)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=C:\Users\cfati\AppData\Local\pypa\virtualenv)
    added seed packages: pip==23.0.1, setuptools==67.4.0, wheel==0.38.4
  activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator

[prompt]>
[prompt]> "c:\Work\Dev\VEnvs\py_pc032_03.10_test1ff1\bin\activate.bat"

(py_pc032_03.10_test1ff1) [prompt]>  python ./code00.py > nul

(py_pc032_03.10_test1ff1) [prompt]>

重要提示

  • FontForge 捆绑的 Python 似乎与其他“常规”Python 示例不兼容,因为它:
  • 使用 GCC(与 VStudio 相反)构建。我认为其结果是它的文件夹结构类似于 Nix
  • 缺陷:缺少一些标准模块(SSLHashLib 等)

因此,尝试通过其中一个(或基于它们的虚拟环境)加载 .pyd 可能会产生UndefinedBehavior

更多调试信息

    • 命令 *:
[cfati@CFATI-W10PC064:e:\Work\Dev\Utils\current\Win]> sopr.bat
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[prompt]> echo %PATH%
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;

[prompt]>
[prompt]> "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" -c "import os;print(os.environ[\"PATH\"]);import fontforge;print(\"\nDone.\")"
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\

Done.

[prompt]>
[prompt]> where ffpython
INFO: Could not find files for the given pattern(s).

[prompt]> set _PATH=%PATH%

[prompt]> set PATH=%_PATH%;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin

[prompt]> where ffpython
c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe

[prompt]>
[prompt]> ffpython -c "import os;print(os.environ[\"PATH\"]);import fontforge;print(\"\nDone.\")"
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\

Done.
  • PowerShellPS):
[cfati@CFATI-W10PC064:E:\Work\Dev\StackExchange\StackOverflow\q073506592]> function prompt { "[PS prompt]> "; }
[PS prompt]>
[PS prompt]> ${Env:PATH}
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;
[PS prompt]>
[PS prompt]> & "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe" -c "import os;print(os.environ[\`"PATH\`"]);import fontforge;print(\`"\nDone.\`")"
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\

Done.
[PS prompt]>
[PS prompt]> where.exe ffpython
INFO: Could not find files for the given pattern(s).
[PS prompt]>
[PS prompt]> ${Env:_PATH} = ${Env:PATH}
[PS prompt]> ${Env:PATH} = ${Env:_PATH} + "c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin"
[PS prompt]> where.exe ffpython
c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\ffpython.exe
[PS prompt]>
[PS prompt]> ffpython -c "import os;print(os.environ[\`"PATH\`"]);import fontforge;print(\`"\nDone.\`")"
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\OpenSSH\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current;e:\Work\Dev\Utils\current\Win;C:\Users\cfati\AppData\Local\Microsoft\WindowsApps;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin;C:\Install\pc032\FontForge\FontForgeBuilds\Version\bin\

Done.

如图所示,它也可以在 PS 下运行,不需要(或很少)手动干预。如果您这边不起作用,请尝试运行:
1.上述步骤
1.FFPython,但从其目录

  1. ffpython -c "import os, sys;os.add_dll_directory(os.path.dirname(sys.executable));import fontforge"
    在调试以下类型的错误时非常有用:

更新 #0

最后一次发现后,很可能 fontforge.pyd 的一些(旧/新版本)dependent .dll 位于 %PATH% 中列出的某些目录中,并且它们在正确版本(从 FontForgebin 目录)之前加载。这要解决一些问题:
1.从上面的列表中读取第一个 URL 并安装 Dependencies
1.然后,当从以下位置启动(Dependencies 工具)时,您必须比较 fontforge.pyd 的依赖 .dll
1.FontForgebin 目录
1.另一个
任何 .dlls在以前的位置
不应该出现在
(或者如果他们是,他们应该有相同的版本)在任何其他(在 %PATH% 中它之前)。你可以使用 GUI 版本或 CmdLine 版本(如下图- FontForgebin 目录在右边):

我用来列出相关 .dll 的命令(显然,您必须调整路径):

"c:\Install\pc064\LucasG\DependenciesWalkerPolitistTexan\Version\Dependencies.exe" -modules "c:\Install\pc032\FontForge\FontForgeBuilds\Version\lib\python3.10\site-packages\fontforge.pyd" | findstr /R "\[Environment\] \[WindowsFolder\]"

另一种方法是在通过 FFPython 启动脚本时使用 ProcMon[MS.Learn]: Process Monitor),如[SO]: C DLL loads in C++ program, not in python Ctypes (@MarkTolonen's answer)所示

  • 找到“错误”的 .dll 后,请执行以下任一操作:
  • %PATH% 中删除它们的目录。实际上,在这种特殊情况下,删除可能就足够了,但为了确保它在任何情况下都能正常工作(包含“重复”的其他目录可能在某些时候出现在某些计算机上),您应该将其设置为某个最小值(是运行任何 Win 应用程序所必需的,并且)适合您。您可以选择(同样,我在myFontForge 安装目录上举例说明-将其调整为适合您的安装目录,一切都会好起来):
  • 通过创建 .bat Package 文件:
set PATH=C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin

ffpython script.py arg0, arg1 :: ...
  • 来自 script.py
import os
os.environ["PATH"] = r"C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;c:\Install\pc032\FontForge\FontForgeBuilds\Version\bin"

import fontforge as ff

这样,加载 .dll(s)发生在一个沙箱环境中(关于 %PATH%),不受任何目录的影响。

  • 当然,还有一个选项(目前可以使用,但有点不方便),可以从 FontForgebin 目录启动脚本(启动脚本前为cd ${FONTFORGE_BIN_DIR}
  • 如果前面的任何一个都不可能(不管是什么原因--尽管我现在想不出一个),那么就删除(或者更好:重命名)它们(请谨慎操作,因为放置它们的应用程序将(很可能)停止工作),但仅将此作为最后手段

相关问题