如何与MATLAB一样构造Python库和路径

2024-06-25 22:31:52 发布

您现在位置:Python中文网/ 问答频道 /正文

在过去的几年里,我已经用matlab编写了几百个用于空间工程的函数,我每天都在使用这些函数。它们都很好地放在一个文件夹中,按子文件夹排序,在matlab中,我只需要在startup.m文件中对根文件夹使用addpath()命令,然后我就可以在启动matlab后立即使用任何函数。你知道吗

我现在也在尝试用python做同样的事情。你知道吗

据我所知,在python中,我不应该像在matlab中那样每个函数都有一个文件,而是将所有函数捆绑在一个py文件中。是这样吗?我试图避免这种情况,因为我有一个强烈的偏好,短脚本,而不是一个巨大的,因为它是更直观的方式对我来说。你知道吗

然后,一旦我有了所有的python脚本,我可以把它们放在任何地方使用它们吗?因为我读到python在这方面的工作方式与matlab不同,并且脚本需要在工作目录中才能导入它们。但是,我希望加载脚本并能够使用它们,而不考虑我的活动工作目录。所以我猜我必须对路径做些什么。我发现我可以使用系统路径插入或者附加,但是这对我来说是一个解决方法,或者是一种方法?你知道吗

考虑到我已经将所有重写的matlab函数放在一个python文件中(我们称之为agfunctions.py文件)保存在一个目录中(我们称之为PythonFunctions)。我生命的核心启动.py然后类似于(我已经将启动文件添加到PYTHONSTARTUP路径):

# startup.py
import os, sys
import numpy as np
import spiceypy as spice

sys.path.append('C:\Users\AG5\Documents\PythonFunctions')
import agfunctions as ag

这些有什么意义吗?这是一种方法,还是python中有更好的方法?你知道吗


Tags: 文件方法函数pyimport路径目录脚本
2条回答

不需要在一个文件中编写所有的matlab函数。你也可以保留你想要的库的文件夹结构。但是,您应该将最深子文件夹中的所有函数写入一个*.py文件。你知道吗

假设您的MATLAB库位于space_engineering文件夹中,设置如下:

space_engineering\
    subfolder1\
        functiongroup1\
            printfoo.m
            printbar.m
    subfolder2\
        ...
    subfolder3\
        ...
    ...

在执行addpath(genpath('\your_path\space_engineering'))之后,子文件夹subfolder*functiongroup*中的所有函数在全局名称空间中可用,如下所示

>> printfoo    % function printfoo does only do fprintf('foo')
foo

我知道这是您希望在迁移的python库中保留的行为。这是有办法做到的。新的python库的结构如下:

space_engineering\
    __init__.py
    subfolder1\
        __init__.py
        functiongroup1.py
        functiongroup2.py
    subfolder2\
        __init__.py
        ...
    subfolder3\
        __init__.py
        ...
    ...

如您所见,最深的子文件夹层functiongroup*的MATLAB结构现在被functiongroup*.py文件替换,即所谓的模块。您必须考虑的唯一折衷是函数printfoo()printbar()现在是在这个.py模块中定义的,而不是单独的.py文件。你知道吗

# content of functiongroup1.py
def printfoo():
    print(foo)

def printbar():
    print(bar)

为了实现与MATLAB中相同的函数调用,必须通过调整每个子文件夹的__init__.py文件,使函数名printfooprintbar在全局命名空间中可用

# content of space_enginieering\subfolder1\__init__.py
from .functiongroup1 import *
from .functiongroup2 import *

以及主文件夹的__init__.py

# content of space_engineering\__init__.py
from .subfolder1 import *
from .subfolder2 import *
from .subfolder3 import *

from .functiongroup1 import *语句将模块functiongroup1中的所有名称加载到subfolder1的命名空间中。依次from .subfolder1 import *将它们转发到全局命名空间。你知道吗

您可以在python控制台(或任何脚本)中这样做,例如:

>>> sys.path.append('\your_path\space_engineering')
>>> from space_engineering import *
>>> printfoo()
foo

这样,您就可以像以前使用MATLAB库一样使用新的python库。你知道吗


但是:在python中不建议使用from xyz import *语句(参见here为什么,这类似于为什么不在MATLAB中使用eval),一些Pythonistas可能会抱怨建议这样做。但是对于您的特殊情况,您坚持创建一个类似MATLAB的python库,这是一个合适的解决方案。你知道吗

好吧,python包可能是解决问题的最佳方法。你可以阅读更多的here。Python包不需要构建,也不总是为了共享而创建的,所以不用担心。你知道吗

假设您有以下文件结构:

Documents/
  startup.py
  PythonFunctions/
    FirstFunc.py
    SecondFunc.py

然后,您可以在PythonFunctions目录中添加文件__init__.py,其中包含下一个内容:

__all__ = ['FirstFunc', 'SecondFunc']

如果您更改了文件名,则必须更新Init文件,所以这可能不是您的最佳解决方案。现在,目录如下所示:

Documents/
  startup.py
  PythonFunctions/
    __init__.py
    FirstFunc.py
    SecondFunc.py

现在是一个包。您可以通过一个import语句导入所有文件并使用它们:

from PythonFunctions import *

result_one = FirstFunc.function_name(some_data)
result_two = SecondFunc.function_name(some_other_data)

如果您的startup.py在其他地方,您可以在作为下一个导入之前更新path

sys.path.append('C:\Users\AG5\Documents')

更详细的解释可以找到here

相关问题 更多 >