【问题标题】:Use input variables across Python scripts在 Python 脚本中使用输入变量
【发布时间】:2015-10-11 22:44:35
【问题描述】:

我试图在另一个 Python 脚本中执行操作后访问函数中包含的变量,但我不想运行函数的操作,我只需要访问返回的值变量ghuser

我尝试了不同的方法来做到这一点,例如在主脚本中将变量的初始值设置为 None,但我遇到的问题是当我将 script1 导入到 script2 时,它会通过脚本运行并再次将有问题的变量重置为无。此外,我尝试将它们包装在一个没有运气的类中。

另外,我尝试使用 if __name__ = '__main__': 运行函数,但我似乎无法弄清楚如何将函数中的值放入 script2 以用作全局变量。

我在这里看到了一些可能有效的答案,例如将函数的值返回给另一个函数以供使用??,但我无法完全确定语法,因为函数似乎不包含变量。

如果我问错了这个问题,请让我知道如何改进它,因为我正在尝试提出“好”的问题,以免我被禁止。我还在学习,我确实在这里提出了很多问题,但我从中学到了很多。

script1.py:

#! /usr/bin/python

import github3
from github3 import login, GitHub, authorize
from getpass import getuser, getpass
import requests

import configparser

def getCreds():
    try:

        user = input('GitHub username: ')
    except KeyboardInterrupt:
        user = getuser()

    password = getpass('GitHub token for {0}: '.format(user))

    gh = login(user, password)


if __name__ == '__main__':

    getCreds()
    exec(open("next_file.py").read())

script2.py

import os
import github3
from github3 import login, GitHub, authorize
from getpass import getuser, getpass
import requests
import csv
import configparser
import sys
import script1
import codecs

gh = script1.gh
user = script1.user

def one_commit_one_file_change_pr():

    #open csv file and create header rows
    with open('c:\\commit_filechange.csv', 'w+') as f:
        csv_writer = csv.writer(f)
        csv_writer.writerow(['Login', 'Title', 'Commits', 'Changed Files','Deletions', 'Additions'])

    for pr in result:
        data = pr.as_dict()
        changes = (gh.repository(user, repo).pull_request(data['number'])).as_dict()    

        if changes['commits'] == 1 and changes['changed_files'] == 1:
        #keep print to console statement for testing purposes
        #print changes['user']['login']


            with open('c:\\commit_filechange.csv', 'a+') as f:
                csv_writer = csv.writer(f)

                csv_writer.writerow([changes['user']['login'], changes['title'], changes['commits'], changes['changed_files']])

one_commit_one_file_change_pr()

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    这是一个我认为是常见做法的解决方案。设置一个名为 global_var.py 的文件(或类似的文件)并在其中存储全局变量。 (See this post by @systemizer) 以下是适用于您的代码的简化版本:

    script1.py

    if __name__=='__main__':
        user = raw_input('GitHub username: ')
        with open('global_var.py','w') as f:
            f.write("user = '%s'" % user)
    password = 'blah'
    gh = '<login(user, password)>'
    

    script2.py

    from script1 import gh
    from global_var import user
    print user
    print gh
    

    【讨论】:

    • @skywalker...感谢您的回复,但我遇到的问题(正如我已经尝试过的那样)是它再次提示用户输入用户名和密码,而我只是需要访问返回给变量的值,而无需再次遍历函数的其余部分。
    • 那么只需在 script1 的底部声明变量,而不是在 if name = main 部分。见编辑
    • @skywalker...我按照您的建议进行了编辑,但得到了相同的结果。当从script2中的script1执行导入时,它会运行代码,找到gh,user = getCreds(),然后运行整个函数,包括提示输入用户名和密码,而我想要的只是返回到gh的值和user。我希望这是有道理的。
    • 我现在看到了问题,这取决于您的应用程序,也许您最好将其设置为环境变量。我不知道如何解决这个问题。你的目的是什么?可能有更好的方法来获取用户名,而不是使用input()
    • 我正在尝试使用 github3 库获取用户名和 pswd 以用于对 github 的身份验证。我还使用用户名传递给 github3 库的存储库对象。我发现这篇文章 stackoverflow.com/questions/14051916/… 讨论了将变量值返回给其他函数。这看起来可行,但我无法正确使用语法。我得到TypeError: other_function() missing 1 required positional argument: 'parameter'
    【解决方案2】:

    这个答案完全基于我的假设,即您只想获得一次用户凭据,并希望稍后在其他脚本中重复使用“n”次。 这是我的做法,


    更新1

    您的问题还与您希望如何组织和运行脚本有关,如果您已将脚本捆绑到 python 包中并运行它们,则以下示例可以工作

    为了。例如

    但如果您计划单独运行单个脚本,那么您别无选择,只能为每个脚本调用登录提示,除非您计划完全删除询问用户凭据并使用文件中的预配置数据。

    脚本1

    from github3 import login
    USER_CREDS = None   # Store raw input credentials here ,not recomended
    GIT_USERS = {}     # global dict to store multiple users with username as key
    
    def getCredentials():
        global USER_CREDS
        if USER_CREDS:
            print "returning user credentials"
            return USER_CREDS
        print "gettting user credentials"
        user = raw_input("Enter Username")
        pwd = raw_input("Enter Password")
    
        USER_CREDS = (user, pwd)
    
        return USER_CREDS
    
    
    def do_login():
        global GIT_USERS
        user, pwd = getCredentials()
        if not GIT_USERS.get(user, None):
            gh = login(user, password=pwd)
            GIT_USERS[user] = gh
        return GIT_USERS[user]
    

    在其他脚本中

    from script1 import do_login
    
    # the first time do_login() is called it asks for user credentials
    print do_login()
    # the next times it just returns the previously collected one
    print do_login()
    

    示例 2

    脚本 3

    from script1 import do_login
    creds = do_login()  
    

    脚本 4

    from script3 import creds
    from script1 import do_login
    print creds
    print do_login() # No input prompt would be provided
    

    【讨论】:

    • @Sanju...你是正确的,但我想在 script1 中运行一次 do_login 以收集凭据,然后将 ghuser 中保存的值传递给其他脚本再次提示他们。如果我在其他脚本中运行do_login(),我会得到位于getCredentials() 的提示。我相信最好的方法是收集凭据并将它们存储在某种性质的加密文件中,然后从那里读出它们。令牌是安全敏感部分。
    • 我现在明白了,如果您单独运行脚本,您可能会如何使用它,是的,每次都会显示提示。我添加了另一个可能的用法示例,如在 script3 中,您可以调用一次 do_login() 并在需要登录凭据的所有其他地方导入凭据,这样您实际上可以避免多次提示。但更好的方法是将凭据安全地存储在文件中并访问它。
    • @Sanju...我看到了将脚本捆绑在 python 包中的更新。这些脚本不会单独运行。想法是让主脚本循环并调用位于单独目录中的所有验证脚本。 exec(open("next_file.py").read()) 将变成一个循环来读取单独目录中的每个文件。我没有使用过 python 包,所以我需要研究如何使用它们,然后尝试你的建议。
    猜你喜欢
    • 2014-03-05
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 1970-01-01
    相关资源
    最近更新 更多