0

我在使用 exchangelib 创建将目录和邮件导出到另一个帐户的脚本时遇到了这个问题。

当我使用“exec”运行代码时,它会返回未定义但之前在相同代码中运行的代码。

这部分不起作用:

exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = naar_account.upload((naar_account.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')

这部分就在它的正上方并且确实有效。这也指“naar_account”:

code = "create = Folder(parent=naar_account.inbox / "
par = ' '.join('"{}" /'.format(word) for word in par.split('/'))[:-1]

exec(code + par + ', name="%s"); create.save()' % fol)

这也有效:

exec('print(naar_account)')

即使重命名它也可以工作,而且它说重命名的部分没有定义:

exec('wtf = naar_account; a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = wtf.upload((wtf.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')

完整代码:

def search_levels(van_account, naar_account):
    for subfolder in van_account.inbox.walk():
        subfolder = subfolder.absolute

        # If '/' means it has subfolders
        if '/' in subfolder.replace(van_account.inbox.absolute + '/', ''):
            # Strip fill path, leave only Inbox path
            par = subfolder.replace(van_account.inbox.absolute + '/', '')
            # Get last item, it's the Dir we need to create
            fol = par.split('/')[-1]
            # Replace last item, it's the Dir, we only need the parent
            par = par.replace(par.split('/')[-1], '')[:-1]

            code = "create = Folder(parent=naar_account.inbox / "
            par = ' '.join('"{}" /'.format(word) for word in par.split('/'))[:-1]

            exec(code + par + ', name="%s"); create.save()' % fol)
            print('[Created] %s' % fol)

            exec('print(naar_account)')

            exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = naar_account.upload((naar_account.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')

        else:
            par = None
            fol = subfolder.replace(van_account.inbox.absolute + '/', '')

            create = Folder(parent=naar_account.inbox, name=fol)
            create.save()
            print('[Created] %s' % fol)

            a =  van_account.inbox / fol
            b = a.all().only('id', 'changekey')
            data = van_account.export(b)
            up = naar_account.upload((naar_account.inbox / fol, d) for d in data)
            print('[UPLOAD] %i mail geupload naar %s' % (len(data), fol))

Traceback (most recent call last):
  File "./migrate.py", line 225, in <module>
    start(van_adres, van_passwd, naar_adres, naar_passwd)
  File "./migrate.py", line 114, in start
    search_levels(van_account, naar_account)
  File "./migrate.py", line 154, in search_levels
    exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); wtf = naar_account; up = wtf.upload((wtf.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.7/site-packages/exchangelib/account.py", line 340, in upload
    is_empty, data = peek(data)
  File "/usr/local/lib/python3.7/site-packages/exchangelib/util.py", line 130, in peek
    first = next(iterable)
  File "<string>", line 1, in <genexpr>
NameError: name 'wtf' is not defined
4

1 回答 1

1

wtfexec's 范围内使用,但似乎没有其他地方,exec它本身在本地范围内。因此wtf将是exec范围内的局部变量。本地人的修改在exec它之外是不可见的,因此wtf根本无法从exec' 的范围之外访问。

生成器表达式中的名称(最左边的for表达式除外)在被调用时被延迟评估__next__。因此wtffromwtf.inbox将在被调用时被查找__next__

这发生在exec范围之外的其他一些函数中,因此wtf,对于后者来说是本地的,在那里找不到。

于 2019-08-31T16:12:16.143 回答