我无法在其他函数中引用原始数据帧,即print_df_in_a_function()
。有人可以告诉我在这里犯的错误吗?
在致电None
时显示print_df_in_a_function()
。
import numpy as np
import pandas as pd
df1 = None
def main():
df1 = pd.DataFrame(np.array([['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr1', 'attr2'])
print(df1)
print_df_in_a_function()
def print_df_in_a_function():
print(df1)
if __name__ == '__main__':
main()
答案 0 :(得分:2)
问题是df1
内的print_df_in_a_function
解析为全球 df1
,而不是df1
本地到main
。这是因为Python具有词法作用域而不是动态作用域。来自wikipedia
范围界定的一个根本区别是"程序的一部分" 手段。在具有词法范围的语言中(也称为静态范围), 名称解析取决于源代码中的位置和 词汇上下文,由命名变量或的位置定义 功能已定义。相比之下,在具有动态范围的语言中 名称解析取决于名称时的程序状态 遇到的是由执行上下文或调用确定的 上下文。在实践中,对于词法范围,变量的定义是 通过搜索其包含的块或函数解决,然后如果那样 无法搜索外部包含块,依此类推,而使用 查询调用函数的动态范围,然后是函数 它调用了调用函数,等等,进行调用 叠加。[4]当然,在这两个规则中,我们首先寻找一个本地 变量的定义。
如果Python确实使用动态作用域,它可以按预期工作。相反,由于词法范围,我们会看到这种行为:
In [1]: import numpy as np
...: import pandas as pd
...:
...: df1 = None
...:
...: def main():
...: df1 = pd.DataFrame(np.array([['a', 5, 9],
...: ['b', 4, 61],
...: ['c', 24, 9]]),
...: columns=['name', 'attr1', 'attr2'])
...:
...: print(df1)
...: print_df_in_a_function()
...:
...: def print_df_in_a_function():
...: print(df1)
...:
...: if __name__ == '__main__':
...: main()
...:
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
None
请注意,如果我们移动print_df_in_a_function
的定义,则名称会解析为df1
内的main
:
In [3]: import numpy as np
...: import pandas as pd
...:
...: df1 = None
...:
...: def main():
...: def print_df_in_a_function():
...: print(df1)
...: df1 = pd.DataFrame(np.array([['a', 5, 9],
...: ['b', 4, 61],
...: ['c', 24, 9]]),
...: columns=['name', 'attr1', 'attr2'])
...:
...: print(df1)
...: print_df_in_a_function()
...:
...: if __name__ == '__main__':
...: main()
...:
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
因为在尝试解析名称时,Python首先检查本地范围(print_df_in_a_function
的本地范围)。然后,如果它没有找到它,它会检查任何包含的范围。在这种情况下,main
的范围有df1
,因此名称解析就此结束。但是,如果您删除df1
中的名称main
,它仍会找到全局df1
:
In [5]: import numpy as np
...: import pandas as pd
...:
...: df1 = None
...:
...: def main():
...: df1 = pd.DataFrame(np.array([['a', 5, 9],
...: ['b', 4, 61],
...: ['c', 24, 9]]),
...: columns=['name', 'attr1', 'attr2'])
...:
...: print(df1)
...: del df1
...: print_df_in_a_function()
...:
...: def print_df_in_a_function():
...: print(df1)
...:
...: if __name__ == '__main__':
...: main()
...:
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
None
答案 1 :(得分:0)
我采用了一个更简单的示例,global
指令解决了这个问题。
df1 = None
def main():
global df1 #This is the magic line that references the global variable
df1 = 1
print(df1)
print_df_in_a_function()
def print_df_in_a_function():
print(df1)
main()
您的代码将是:
import numpy as np
import pandas as pd
df1 = None
def main():
global df1
df1 = pd.DataFrame(np.array([['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr1', 'attr2'])
print(df1)
print_df_in_a_function()
def print_df_in_a_function():
print(df1)
if __name__ == '__main__':
main()
答案 2 :(得分:0)
为此,您需要了解变量范围的工作原理。看看这个!
def my_func():
index3 =5000
print(index3)
index3=10;
print(index3)
my_func()
输出:
10
5000
注意:即使有两个index3,您可能会认为它们是相同的。但他们不是
my_func中的index3是一个局部变量。虽然程序中的那个(不在函数中的那个)index3是不同的!那么在上面的代码中发生的是第一个print(index3)在我的代码中打印index3(不在任何函数中......只是在我的程序中)然后调用my_func()并在my_func()中打印(index3)打印本地变量index3
看看这个!
def my_func():
print(index3)
index3=10;
print(index3)
my_func()
输出:
10
10
现在两次看到index3都是相同的10这意味着它会打印全局变量两次。
现在看:
def my_func():
index3 =index3+1
index3=10;
print(index3)
my_func()
输出:
10
Traceback (most recent call last):
File "/home/mr/func.py", line 6, in <module>
my_func()
File "/home/mr/func.py", line 2, in my_func
index3 =index3+1
UnboundLocalError: local variable 'index3' referenced before assignment
为什么?
因为这个index3 =index3+1
所以当它看到一个index3 =它会创建一个局部变量。所以index3 = 0表示将0赋给局部变量。
但是index3 = index3 + 1会让人感到困惑!它认为
等你想让我将局部变量index3指定为局部变量index3 + 1吗?但你还没有宣布它!
def my_func():
global index3
index3 =index3+1
print(index3)
index3=10
print(index3)
my_func()
print(index3)
输出:
10
11
11
现在它在函数中获取全局值并且它会发生变化。所以index3由函数改变。
注意:使用全局变量是错误的编码实践。
def getIndex3():
return index3
def my_func():
index3 = getIndex3()
index3 =index3+1
print(index3)
index3=10
print(index3)
my_func()
print(index3)
现在输出:
10
11
10
所以在你的情况下。
def print_df_in_a_function():
print(df1)
这也解决了程序中的df1=None
(全局位于顶部)。并不代表你的主要df1
。
但是,您可以通过将df1
(在主中)传递到您的
print_df_in_a_function(df1)
现在发生的事情是df1
具有值(您的数据帧)将传递给您的print_df_in_a_function(df1):
,现在您可以打印该值。像这样,
import numpy as np
import pandas as pd
df1 = None
def main():
df1 = pd.DataFrame(np.array([['a', 5, 9],
['b', 4, 61],
['c', 24, 9]]),
columns=['name', 'attr1', 'attr2'])
print(df1)
print_df_in_a_function(df1)
def print_df_in_a_function(df1):
print(df1)
if __name__ == '__main__':
main()
输出:
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
name attr1 attr2
0 a 5 9
1 b 4 61
2 c 24 9
>>>