如何在 Python 中声明和调用基于其他分层变量的动态变量?
How can I declare and call a dynamic variable based on other hierarchical variables in Python?
我正在尝试编写一个抓取程序,当我指定要从中下载的文件夹路径时,它将从 outlook 帐户下载附件。我有工作代码,但文件夹位置硬编码如下:-
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_folder = namespace.Folders.Item('Personal') #Inbox of interest
subfolder = root_folder.Folders['Inbox'].Folders['Holidays'].Folders['2009'].Folders['June'] #I have Holidays,2009 and June folders in that hierarchical order in the mailbox called Personal
Messages = subfolder.Items
使用代码,我可以根据其他预设参数从收件箱中抓取电子邮件和附件。
但是,我对动态执行此操作很感兴趣,这样根据嵌套文件夹的数量,我将能够构建 子文件夹 变量,如以上代码。我已经使用以下代码进行了尝试。
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_mailbox = str(input("Please Enter the Root folder name for the mailbox to scrape from:")) #Mailbox to download from i.e. may be like "Personal" above.
if (root_mailbox == ""):
print("You cannot leave this empty. Please insert the root folder name.")
else:
root_folder = namespace.Folders.Item(root_mailbox)
sub_folders_num = int(input('How many subfolders are to be iterated on in the mailbox. Remember this has to be a number.')) #Specify the number of folders
foldernames = [] #List to append to names values
for i in range(1,sub_folders_num+1):
i = input("Input folder name(s) starting with the one closest to the root folder")
foldernames.append(i)
subfolder = root_folder.Folders[foldernames[0]].Folders[foldernames[1]].Folders[foldernames[2]] # Subfolder path but still "manually" specified
Messages = subfolder.Items
subfolder 变量将有效,但该过程仍然是手动的。我怎样才能根据 sub_folders_num 和使用循环中捕获的列表值构建的子文件夹路径动态指定“文件夹”?这将有助于创建一个更动态的抓取工具,我可以从任何收件箱文件夹路径下载 emails/attachments。
您可以将此作为 reduction 而不是 foldernames
使用 getattr
来动态获取下一个属性。
from functools import reduce
subfolder = reduce(lambda x, y: getattr(x, x.Folders[y]), foldernames, root_folder)
或者,一种不太优雅但更易于调试的非功能性方法:
subfolder = root_folder
for folder_name in foldernames:
subfolder = subfolder.Folders[folder_name]
最终结果应该与reduce
方法相同。
看来您需要递归地遍历 Outlook 中的所有文件夹。这是一个示例 VBA 宏,因此您可能会看到 属性 的序列和完成工作的方法调用:
private void EnumerateFoldersInDefaultStore()
{
Outlook.Folder root =
Application.Session.
DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
}
// Uses recursion to enumerate Outlook subfolders.
private void EnumerateFolders(Outlook.Folder folder)
{
Outlook.Folders childFolders = folder.Folders;
if (childFolders.Count > 0)
{
foreach (Outlook.Folder childFolder in childFolders)
{
// Write the folder path.
Debug.WriteLine(childFolder.FolderPath);
// Call EnumerateFolders using childFolder.
EnumerateFolders(childFolder);
}
}
}
我正在尝试编写一个抓取程序,当我指定要从中下载的文件夹路径时,它将从 outlook 帐户下载附件。我有工作代码,但文件夹位置硬编码如下:-
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_folder = namespace.Folders.Item('Personal') #Inbox of interest
subfolder = root_folder.Folders['Inbox'].Folders['Holidays'].Folders['2009'].Folders['June'] #I have Holidays,2009 and June folders in that hierarchical order in the mailbox called Personal
Messages = subfolder.Items
使用代码,我可以根据其他预设参数从收件箱中抓取电子邮件和附件。
但是,我对动态执行此操作很感兴趣,这样根据嵌套文件夹的数量,我将能够构建 子文件夹 变量,如以上代码。我已经使用以下代码进行了尝试。
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")
root_mailbox = str(input("Please Enter the Root folder name for the mailbox to scrape from:")) #Mailbox to download from i.e. may be like "Personal" above.
if (root_mailbox == ""):
print("You cannot leave this empty. Please insert the root folder name.")
else:
root_folder = namespace.Folders.Item(root_mailbox)
sub_folders_num = int(input('How many subfolders are to be iterated on in the mailbox. Remember this has to be a number.')) #Specify the number of folders
foldernames = [] #List to append to names values
for i in range(1,sub_folders_num+1):
i = input("Input folder name(s) starting with the one closest to the root folder")
foldernames.append(i)
subfolder = root_folder.Folders[foldernames[0]].Folders[foldernames[1]].Folders[foldernames[2]] # Subfolder path but still "manually" specified
Messages = subfolder.Items
subfolder 变量将有效,但该过程仍然是手动的。我怎样才能根据 sub_folders_num 和使用循环中捕获的列表值构建的子文件夹路径动态指定“文件夹”?这将有助于创建一个更动态的抓取工具,我可以从任何收件箱文件夹路径下载 emails/attachments。
您可以将此作为 reduction 而不是 foldernames
使用 getattr
来动态获取下一个属性。
from functools import reduce
subfolder = reduce(lambda x, y: getattr(x, x.Folders[y]), foldernames, root_folder)
或者,一种不太优雅但更易于调试的非功能性方法:
subfolder = root_folder
for folder_name in foldernames:
subfolder = subfolder.Folders[folder_name]
最终结果应该与reduce
方法相同。
看来您需要递归地遍历 Outlook 中的所有文件夹。这是一个示例 VBA 宏,因此您可能会看到 属性 的序列和完成工作的方法调用:
private void EnumerateFoldersInDefaultStore()
{
Outlook.Folder root =
Application.Session.
DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
}
// Uses recursion to enumerate Outlook subfolders.
private void EnumerateFolders(Outlook.Folder folder)
{
Outlook.Folders childFolders = folder.Folders;
if (childFolders.Count > 0)
{
foreach (Outlook.Folder childFolder in childFolders)
{
// Write the folder path.
Debug.WriteLine(childFolder.FolderPath);
// Call EnumerateFolders using childFolder.
EnumerateFolders(childFolder);
}
}
}