您正在尝试做的事情 - 创建与文件同名的动态局部变量是我不经常遇到的模式,并且可能会出现问题,但是我已经展示了一种方法下面也是。您应该尝试直接使用 dict 键。您可以创建一个 dict 子类,您可以在其中将键作为属性访问,类似于 pandas 允许列作为属性或使用常规 dict __getitem__ 机制访问的方式。例如,
class AttributeDict(dict):
"""Access keys as attributes."""
@classmethod
def _forbidden(cls, key):
"""Key not allowed if it matches a class (not instance) attribute."""
return key in dir(cls)
def __setitem__(self, key, val):
"""Regular dict setitem + attribute set."""
# key must be a regular python identifier, in order to be accesible as
# an attribute.
if not str.isidentifier(key):
raise ValueError("'%s' it not a valid Python identifier. "
"Cannot set attribute." % key)
# Prevent accidentally overwriting an important class attribute.
if self._forbidden(key):
raise ValueError("Key '%s' is a class attribute" % key)
super().__setitem__(key, val)
setattr(self, key, val)
def __delitem__(self, key):
"""Regular dict delitem + attribute removal."""
super().__delitem__(key)
delattr(self, key)
这个类还没有完成,因为它不会阻止直接设置一个属性,这可能会使 dict 键值不同步。
In [4]: x = AttributeDict()
In [5]: x['A'] = 1
In [6]: x['2A'] = 1
ValueError: '2A' it not a valid Python identifier. Cannot set attribute.
In [7]: x['B'] = 2
In [8]: x.A
Out[8]: 1
In [9]: x.B
Out[9]: 2
您的具体用例如下所示:
dfs = AttributeDict()
for x in files:
dfs[x] = pd.read_csv(x)
dfs.file1
dfs.file2
现在,要回答原始问题,您可以使用locals()。
for x in files:
if not str.isidentifier(x):
raise ValueError("'%s' not a valid identifier." % x)
locals()[x] = pd.read_csv(x)
一个有效标识符但与重要的局部变量冲突的文件名将造成严重破坏!例如,如果您在 IPython 会话中并且执行 locals()['exit'] = None,则可以再使用 exit 命令!