Почему функция dows exe c () работает в необработанном коде, а не в функции или классе в Python 3.7? - PullRequest
0 голосов
/ 19 февраля 2020

Ниже я показываю 2 примера использования функции exe c () в Python 3.7, один в классе и один в необработанном коде. Только последний работает правильно. Может ли кто-нибудь объяснить мне возможные причины и предложить решения?

#!/usr/bin/env python

import pandas as pd

################################# exec() WITHIN A CLASS ###################################
class Test:

    def __init__(self):
        pass

    def f(self):
        pose, frame, min_complexE, min_lEfree, best_structvar, best_conf, complexE, ligandE_bound, proteinE_bound, \
        min_lEfree = [None] * 10
        table = pd.read_table("sample_scores.txt", delim_whitespace=True, skiprows=[0])  # 1st line is a comment
        table_columns = table.columns
        for i, row in table.iterrows():
            # Variable assignemnt
            for varname in ["pose", "frame", "min_complexE", "min_lEfree", "best_structvar", "best_conf",
                            "complexE", "ligandE_bound", "proteinE_bound", "min_lEfree", "Eint"]:
                if varname in table_columns:
                    exec("%s = %s" % (varname, row[varname]), globals(), globals())
                else:
                    exec("%s = None" % (varname), globals(), globals())

            print("proteinE_bound within class =", proteinE_bound)

    def caller1(self):
        self.f()

    def caller2(self):
        self.caller1()

Test().caller2()

################################# exec() IN RAW CODE ###################################
pose, frame, min_complexE, min_lEfree, best_structvar, best_conf, complexE, ligandE_bound, proteinE_bound, \
min_lEfree = [None] * 10
table = pd.read_table("sample_scores.txt", delim_whitespace=True, skiprows=[0])  # 1st line is a comment
table_columns = table.columns
for i, row in table.iterrows():
    # Variable assignemnt
    for varname in ["pose", "frame", "min_complexE", "min_lEfree", "best_structvar", "best_conf",
                    "complexE", "ligandE_bound", "proteinE_bound", "min_lEfree", "Eint"]:
        if varname in table_columns:
            exec("%s = %s" % (varname, row[varname]), globals(), globals())
        else:
            exec("%s = None" % (varname), globals(), globals())
    print("proteinE_bound as raw code =", proteinE_bound)

Содержимое файла "sample_scores.txt":

# Contains all results. For the best result for each compound please refer to file BEST_RESULTS.
molname Eint    complexE    ligandE_bound   proteinE_bound  stereoisomer    ionstate    tautomer    pose    frame
LEM00001847 -63.000496 -17406.593934 -84.868633 -17258.724804 1 1 1 1 571
LEM00001847 -62.412897 -17474.918135 -64.778724 -17347.726515 1 1 1 1 171
LEM00001847 -61.249384 -17423.452346 -82.875735 -17279.327226 1 1 1 1 531

1 Ответ

0 голосов
/ 20 февраля 2020

Я нашел ответ, хотя в нем все еще есть некоторые неясные моменты. По сути, мне пришлось удалить строку

pose, frame, min_complexE, min_lEfree, best_structvar, best_conf, complexE, ligandE_bound, proteinE_bound, \
        min_lEfree = [None] * 10

, где я инициализировал переменные, которые должны быть назначены exe c (). Если эти переменные не существуют, они успешно добавляются в глобальные переменные () и доступны в функции как отдельные переменные.

Теперь непонятные точки:

1) Даже если Я инициализирую эти 10 переменных как None, в каждой итерации for l oop их значения обновляются в словаре globals (), но не тогда, когда я вызываю их имена как отдельные переменные.

2) Согласно документы. python .org exec(__object, __globals=..., __locals=...). Кажется, что только данный словарь '__globals' обновляется новыми переменными. Поэтому, хотя в моем коде выше я использую

exec("%s = %s" % (varname, row[varname]), globals(), globals())

, это также работает

exec("%s = %s" % (varname, row[varname]), locals(), globals())

В моем понимании, последний является правильным способом, потому что вы хотите, чтобы эти переменные были созданы внутри контекст функции, а именно как локальные переменные. Но тогда почему exe c () обновляет данные __globals, а не данные __locals?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...