在Python中添加使用循环的NumberSerd变量?
我看过很多类似的问题,但是我认为这是重复的,因为我还没有找到任何特定的解决方案。大多数类似的线程几乎是在说根本不这样做,而是使用另一种方法,但是我认为我在我的情况下没有太多选择,会尝试用下面的一些示例代码来解释。我的问题如下:
假设我有一个称为folder1的变量,其中包含configurationFile中给定键的路径的值,然后我想让用户选择地将更多文件夹添加到配置文件中,并自动分配该值对于一个称为folder2,folder3等的新变量,
让我们假装我有一个看起来像这样的config.ini
[Default]
folder1 = /var/www/example.com
folder2 = /var/www/example2.com
folder3 = /var/www/example3.com
webserver = nginx
some_other_stuff = Hello world!
,我的脚本看起来像是这样的
import configparser
config = configparser.ConfigParser()
config.read("config.ini")
# Here i would like to assign variables for each value of the keys in the ini-file
folder1 = config["Default"]["folder1"]
for num in range(2, 11):
if config.has_option("Default", f"folder{num}"):
# Here i would like something like var{num} = folder{num}
globals()[f"folder{num}"] = config["Default"][f"folder{num}"]
webserver = config["Default"]["webserver"]
some_other_stuff = config["Default"]["some_other_stuff"]
print(f"Folder 1 is {folder1}, webserver is {webserver}, and some other stuff is {some_other_stuff}")
# print(folder2) --> NameError: name 'folder2' is not defined. Did you mean: 'folder1'?
自我解释,但是由于我什么都没有尝试过 考虑到我有很多类似的configurationOptions,并且要轻松地比较值等。
folders_list = []
for num in range(1, 11):
if config.has_option("Default", f"folder{num}"):
folders_list.append(f"folder{num}")
# Printing one folder work:
print(config["Default"][folders_list[0]])
# And printing a range "sort of" works as long as you know the number of folders created on beforehand
# But i would like to let the user add up to 10 paths optionally without needing to change the code
for num in range(0, 3):
print(f'{config["Default"][folders_list[num-1]]}')
我尝试使用另一种方法来解决它,这给了我其他问题( ,与仅在自己的变量中存储每个值相比,这种打字方式很难跟踪,如果我需要对这些值进行大量比较操作,并且如果我的话,这也不是很好希望用户在配置文件中选择添加任何数量的文件夹(最多10个),而不必编辑SourceCode本身。我还指出,如果我尝试根据文件夹的len做事,使用这种方法会弄乱事情。
if len(folders_list) >= 2:
print(config["Default"][folders_list[0]])
#else:
#print(config["Default"][folders_list[0:len(folders_list) -1]]) --> AttributeError: 'list' object has no attribute 'lower'
事先感谢!
I've seen a lot of similar questions but I don't think this is a duplicate since I haven't found any specific solutions for this. Most similar threads is pretty much saying not to do it this way at all, and use another method instead, but I think I don't have much choise in my case, will try to explain with some example-code below. My question is as follows:
Let's say I have a variable called folder1, that contains the value to a path of a given key in a configurationfile, I then want to let the user optionally add more folders to the configurationfile, and automatically assign that value to a new variable called folder2, folder3 etc.
Let's pretend I have a config.ini that looks like this
[Default]
folder1 = /var/www/example.com
folder2 = /var/www/example2.com
folder3 = /var/www/example3.com
webserver = nginx
some_other_stuff = Hello world!
And my script looks like this
import configparser
config = configparser.ConfigParser()
config.read("config.ini")
# Here i would like to assign variables for each value of the keys in the ini-file
folder1 = config["Default"]["folder1"]
for num in range(2, 11):
if config.has_option("Default", f"folder{num}"):
# Here i would like something like var{num} = folder{num}
globals()[f"folder{num}"] = config["Default"][f"folder{num}"]
webserver = config["Default"]["webserver"]
some_other_stuff = config["Default"]["some_other_stuff"]
print(f"Folder 1 is {folder1}, webserver is {webserver}, and some other stuff is {some_other_stuff}")
# print(folder2) --> NameError: name 'folder2' is not defined. Did you mean: 'folder1'?
It's sort of self-explaining what I'm trying to accomplish, but since nothing I've tried so far worked, I tried to get around it using another method, that gives me other problems instead (and are way messier to type, considering I have tons of different configurationoptions like this and want to easily be able to compare values etc..
folders_list = []
for num in range(1, 11):
if config.has_option("Default", f"folder{num}"):
folders_list.append(f"folder{num}")
# Printing one folder work:
print(config["Default"][folders_list[0]])
# And printing a range "sort of" works as long as you know the number of folders created on beforehand
# But i would like to let the user add up to 10 paths optionally without needing to change the code
for num in range(0, 3):
print(f'{config["Default"][folders_list[num-1]]}')
As explained, this way of typing is very hard to keep track of in my opinion compared to just storing each value in it's own variable if I need to do a lot of comparing-operations on these, and also this doesn't really work well if I want the user to optionally add any amount of folders (up to 10) in the configfile and not having to edit the sourcecode itself. I also noted that using this method will mess up things if I try to do things based on the len of folders_list.
if len(folders_list) >= 2:
print(config["Default"][folders_list[0]])
#else:
#print(config["Default"][folders_list[0:len(folders_list) -1]]) --> AttributeError: 'list' object has no attribute 'lower'
Thanks on beforehand!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我在这里详细说明我的评论:
您将很容易接触到的最近的东西,就是将文件夹分配给字典并使用数字键,或将它们添加到列表中。
我明白您的意思是,当不得不使用这么多索引时,它不支持代码的可读性。我想到的一种解决方案会创建一个课程。但是,您想使代码更具可读性的所有事物使情况在背景中变得更加复杂。
使用类
,但这虽然看起来更好,但恕我直言不多,因为它对于处理数据的简单任务来说太多了,这是通过词典或任何类型表示的
configparser.configparser()
的输出。您想要什么以及为什么这是一个坏主意:
如果我正确理解它,您想在运行时分配变量。出现两个问题。
第一个是您在运行时创建变量,因此您不知道代码中会发生什么。您不知道您在代码中有多少个变量,例如
var_1,var_2等。
。如果您不知道它是否存在,该如何访问变量?这就是为什么词典在这种情况下如此方便的原因。使用dict.values(),dict.items(),dict.keys(),...
之类的属性,您每次都有其内容概述。此外,如果您在运行时定义变量,则无法在编程时使用它们。如果您使用示例

var_3 == var_4
用于比较数据,但是您定义var_3
和var_4
在运行时,python将无法运行,两个变量尚未定义并抛出nameError
:您可以通过将此类语句也放入
exec()
或更可能eval()
中来解决此问题,但这使事情变得复杂且丑陋。第二个是安全性,我已经讨论了
您可以在运行时创建自定义命名变量:
这将在每次迭代中创建一个变量
var_2,var_3,...
,并将文件夹分配给它。但是,正如链接答案中所写的,在处理用户输入时,EXEC是危险的。如果您只能访问配置文件,这可能是一个合理的风险,只有问题(1)可能会烦恼您。但是,如果其他人有访问权限,或者您正在创建诸如Web应用程序之类的STH,攻击者可能会访问您的计算机,从而可以访问您的配置文件。在这种特定情况下,我认为可以启动链接答案中的攻击,因为您正在读取config和configparser正确逃脱/封闭字符串的字符串,因此无法将其评估为陈述。但是,如果ConfigParser无法正确执行此操作,则您的应用程序将不存在一个安全孔,而是由于所需的功能,而是由于对内置方法的过度复杂化(
eval()< / code> /
exec()
)例如,当您的配置文件get更改为这样的sth时,将不会执行命令,但是使用exec/eval可以是这样,并且要牢记利用exec/exec的所有可能性并不容易评估。因此,不使用它们是很常见的,尤其是当它们与您无法控制的数据保持联系时。
对于不同的应用程序,此类攻击是不同的,并且取决于数据/EXEC的存在。但是,如果可以利用这一点,则攻击者可以导入任何现有模块并运行代码。
I'm elaborating here to my comment:
The nearest possible thing you will reach easily, is to assign your folders either to a dictionary and use numeric keys, or add them to a list.
I get your point, that it's not supporting the readability of your code when having to use so many indices. One solution coming to my mind would create a class. But all things you're trying to make your code more readable make things more complicated in the background, I guess.
Using a class
But this, although it might look better, makes not much sense imho, as it's too much for such a simple task of handling data, which is represented best via a dictionary or whatever the type of the output of
configparser.ConfigParser()
is.What you want and why it's a bad idea:
If I understand it correctly, you want to assign variables at runtime. There arise two problems.
The first one is, that you're creating variables at runtime, thus you don't know what happens in your code. You don't know exactly how many variables like
var_1, var_2, etc.
you have in your code. How will you access a variable if you don't know if it exists? That's why dictionaries are so handy in such cases. With attributes likedict.values(), dict.items(), dict.keys(), ...
you have at every time an overview on its contents.Furthermore, if you define variables at runtime, you cannot use them whilst programming. If you use for example

var_3 == var_4
to compare data, but you definevar_3
andvar_4
at runtime, Python won't run, as both variables are not (yet) defined and throws aNameError
:You can solve this problem by putting such statements also into
exec()
or more likelyeval()
, but that makes things complicated and ugly.The second one is the security, which I have discussed here already.
You can create custom named variables at runtime like so:
This creates a variable
var_2, var_3, ...
at each iteration and assigns the folder to it. But as written in the linked answer, exec is dangerous when handling user input. If only you have access to your config file, this might be a reasonable risk and only problem (1) might annoy you. But there's a high risk if others have access, or you're creating sth like a web application, where attackers might gain access to your machine and thus get access to your config file.In this specific case, I don't think that an attack like in the linked answer can be started, because you're reading a string from the config and the configparser correctly escapes/encloses your string, so that it cannot be evaluated as a statement. But if the configparser would not do this correctly, your application would get a security hole does not exist because of needed functionality but because of overcomplicated misuse of builtin methods(
eval()
/exec()
)When for example your config file get's changed to sth like this, the command will not be executed, but using exec/eval this can be the case and it's not that easy to have all possibilities in mind to exploit exec/eval. Therefore, it's very common to do not use them, especially when they will get in touch with data which you have not 100% under your control.
Such attacks are different for different applications and depend on the handling of the data/the existence of eval/exec. But if this could be exploited, an attacker could import any existing modules and run code.