lzb1001 发表于 2023-5-15 21:19:48

根据返回的错误提示,FunY到底是函数还是变量名?

def FunX(x):
        def FunY(y):
                return x * y
        return FunY()


众所周知,上面的FunY是函数,而且是FunX()的内部函数。

我知道调用内部函数FunY()或报错,但注意看返回的错误提示(下面红色字体翻译):

>>> FunY(5)
Traceback (most recent call last):
File "<pyshell#68>", line 1, in <module>
    FunY(5)
NameError: name 'FunY' is not defined # 名称错误:FunY没有被定义!


【我的问题】

在错误提示里,好像并不是说FunY是函数,而是一个变量名,怎么回事呢?

isdkz 发表于 2023-5-15 21:20:10

在Python中,函数也是一种对象,因此也可以被赋值给变量。在这个例子中,当FunX()函数被调用时,它返回了FunY()函数对象,但它并没有将FunY()函数对象赋值给任何变量名。因此,当你尝试直接调用FunY()函数时,Python会抛出NameError,提示你FunY没有被定义。这并不意味着FunY是一个变量名,而是因为Python无法找到FunY()函数对象的引用。如果你想调用FunY()函数,可以通过调用FunX()来获取FunY()函数对象:FunX(2)(3)将返回6。

isdkz 发表于 2023-5-15 21:21:23


def FunX(x):
      def FunY(y):
                return x * y
      return FunY

FunX(2)(3)

lzb1001 发表于 2023-5-15 21:23:22

isdkz 发表于 2023-5-15 21:20
在Python中,函数也是一种对象,因此也可以被赋值给变量。在这个例子中,当FunX()函数被调用时,它返回了Fu ...

但我无论是:

>>> FunX(8)
Traceback (most recent call last):
File "<pyshell#102>", line 1, in <module>
    FunX(8)
File "<pyshell#101>", line 4, in FunX
    return FunY()
TypeError: FunY() missing 1 required positional argument: 'y' # FunY()缺位置参数

或者:

>>> FunX(8)(5)
Traceback (most recent call last):
File "<pyshell#67>", line 1, in <module>
    FunX(8)(5)
File "<pyshell#62>", line 4, in FunX
    return FunY()
TypeError: FunY() missing 1 required positional argument: 'y' # FunY()缺位置参数

都是返回错误的提示,都是提示说FunY()缺位置参数

到底要怎么才能不会返回错误的提示呢?

isdkz 发表于 2023-5-15 21:24:45

lzb1001 发表于 2023-5-15 21:23
但我无论是:

>>> FunX(8)


return FunY()             # 这里的括号是多余的

应该是 return FunY

lzb1001 发表于 2023-5-15 21:29:44

本帖最后由 lzb1001 于 2023-5-15 21:33 编辑

isdkz 发表于 2023-5-15 21:24
return FunY()             # 这里的括号是多余的

应该是 return FunY

return FunY()             # 不能保留括号吗?

如果想保留括号即返回FunY()函数的值(即保留上面的括号),应该要怎么做呢?

我就是没搞懂:下面两个例子就差了一个括号,为何返回的截然不同?而且第一个例子返回的还是错误的提示?

例1:
>>> def FunX(x):
      def FunY(y):
                return x * y
      return FunY()

>>> FunX(8)
Traceback (most recent call last):
File "<pyshell#52>", line 1, in <module>
    FunX(8)
File "<pyshell#51>", line 4, in FunX
    return FunY()
TypeError: FunY() missing 1 required positional argument: 'y'

例2:
>>> def FunX(x):
      def FunY(y):
                return x * y
      return FunY

>>> FunX(8)
<function FunX.<locals>.FunY at 0x00000209FD242558>

isdkz 发表于 2023-5-15 21:32:37

lzb1001 发表于 2023-5-15 21:29
return FunY()             # 不能保留括号吗?

如果想保留括号即返回FunY()函数的值(即保留上面的括 ...

FunY定义的时候是需要传参数的,带括号是调用函数返回结果,如果你要保留括号你就得传相对应的参数

def FunX(x):
      def FunY(y):
                return x * y
      return FunY(3)

FunX(2)

不过这样就失去了闭包的意义了

lzb1001 发表于 2023-5-15 21:39:21

isdkz 发表于 2023-5-15 21:32
FunY定义的时候是需要传参数的,带括号是调用函数返回结果,如果你要保留括号你就得传相对应的参数

de ...

1、FunX(2)(3)这样还不行?

2、另外如果下面这样也不对:

def FunX(x):
      def FunY():
                return x * y
      return FunY()

>>> FunX(8)
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
    FunX(8)
File "<pyshell#57>", line 4, in FunX
    return FunY()
File "<pyshell#57>", line 3, in FunY
    return x * y
NameError: name 'y' is not defined

>>> i = FunX(8)
Traceback (most recent call last):
File "<pyshell#59>", line 1, in <module>
    i = FunX(8)
File "<pyshell#57>", line 4, in FunX
    return FunY()
File "<pyshell#57>", line 3, in FunY
    return x * y
NameError: name 'y' is not defined

>>> i
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
    i
NameError: name 'i' is not defined

>>> type(i)
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
    type(i)
NameError: name 'i' is not defined

>>> i(5)
Traceback (most recent call last):
File "<pyshell#62>", line 1, in <module>
    i(5)
NameError: name 'i' is not defined

>>> FunX(8)(5)
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
    FunX(8)(5)
File "<pyshell#57>", line 4, in FunX
    return FunY()
File "<pyshell#57>", line 3, in FunY
    return x * y
NameError: name 'y' is not defined

isdkz 发表于 2023-5-15 21:41:12

lzb1001 发表于 2023-5-15 21:39
1、FunX(2)(3)这样还不行?

2、另外如果下面这样也不对:


注意看这两个的区别

1、
def FunX(x):
      def FunY(y):
                return x * y
      return FunY

FunX(2)(3)

2、
def FunX(x):
      def FunY(y):
                return x * y
      return FunY(3)

FunX(2)

sfqxx 发表于 2023-5-15 22:32:40

在错误提示中说 " NameError: name 'FunY' is not defined" 意味着 'FunY'这个名称或变量没有被定义。虽然我们知道FunY是一个函数,但是当你尝试像这样调用 FunY(5)时,解释器会寻找名为 "FunY"的变量,并且发现它没有被定义。

可以看出,在FunX内部定义的FunY函数只能在FunX中使用,如果要访问FunY,则必须像下面这样将其返回:


def FunX(x):
      def FunY(y):
                return x * y
      return FunY # 返回FunY函数对象

# 调用FunX()并将返回的函数对象分配给fun变量
fun = FunX(3)

# 现在可以通过fun(FunY函数对象)来调用FunY()函数
result = fun(4)
print(result) # 输出 12


注意此时 FunX( ) 返回 FunY 函数本身而不是执行 FunY(), 因此在调用FunX( ) 时,要把它的返回赋值给变量才能使用 FunY() 函数。

wp231957 发表于 2023-5-16 07:57:25

lzb1001 发表于 2023-5-15 21:39
1、FunX(2)(3)这样还不行?

2、另外如果下面这样也不对:


>>> wp=print
>>> wp
<built-in function print>
>>> wp("我是谁,我可以做什么")
我是谁,我可以做什么
>>> wp2=print()

>>> wp2
>>> wp("这里wp2 相当于print函数的返回值")
这里wp2 相当于print函数的返回值
>>>

wp231957 发表于 2023-5-16 08:06:25

电脑无法识别内部函数,它不会提示你FUNY是一个内部函数你无法再外部调用它


它只知道找不到 FUNy   所以NameError: name 'FunY' is not defined 这是再普通不过的错误信息了

lzb1001 发表于 2023-5-16 09:32:14

wp231957 发表于 2023-5-16 07:57
>>> wp=print
>>> wp



>>> print
<built-in function print>
>>> print("我是谁,我可以做什么")
我是谁,我可以做什么
>>> print(repr("我是谁,我可以做什么"))
'我是谁,我可以做什么'
>>> print(str("我是谁,我可以做什么"))
我是谁,我可以做什么
>>> wp = print# 1 理解
>>> wp # 2 理解
<built-in function print>
>>> wp("我是谁,我可以做什么") # 3 理解
我是谁,我可以做什么
>>> wp(repr("我是谁,我可以做什么"))
'我是谁,我可以做什么'
>>> wp(str("我是谁,我可以做什么"))
我是谁,我可以做什么
>>> print()

>>> wp2 = print() # 4 不理解意思

>>> wp2 # 5
>>> type(wp2)
<class 'NoneType'>
>>> wp("这里wp2 相当于print函数的返回值") # 6 不理解,上面的print函数的返回值为none吧?
这里wp2 相当于print函数的返回值

wp231957 发表于 2023-5-16 09:38:12

lzb1001 发表于 2023-5-16 09:32
>>> print

>>> print("我是谁,我可以做什么")


>>> wp2 = print() # 4 不理解意思    尝试把print函数的返回值赋给wp2 这个变量

>>> type(wp2)
<class 'NoneType'>    因为print没有返回值所以你要取它的返回值 就是none所以这里你用type测试肯定是NoneType

wp231957 发表于 2023-5-16 09:39:05

lzb1001 发表于 2023-5-16 09:32
>>> print

>>> print("我是谁,我可以做什么")


>>> s=None
>>> type(s)
<class 'NoneType'>
>>>

lzb1001 发表于 2023-5-16 10:33:43

wp231957 发表于 2023-5-16 09:39
>>> s=None
>>> type(s)



>>> wp6 = print('lzb')
lzb
>>> type(wp6)
<class 'NoneType'>

上面wp6返回值是lzb,它是一个字符串,为何 type(wp6)返回的类型是NoneType?

wp231957 发表于 2023-5-16 10:40:26

lzb1001 发表于 2023-5-16 10:33
>>> wp6 = print('lzb')
lzb
>>> type(wp6)


错,那是print的输出信息,不是返回值
print的返回值永远是none

wp231957 发表于 2023-5-16 11:02:36

lzb1001 发表于 2023-5-16 10:33
>>> wp6 = print('lzb')
lzb
>>> type(wp6)


很多东西都可以自己去尝试
要注意一下,再py中测试和再shell中测试还有细微区别到时你也不用问为什么因为那就是交互模式下特有的一些特性

Lynn_oyl 发表于 2023-5-25 20:20:34

Traceback (most recent call last):
File "<pyshell#68>", line 1, in <module>
    FunY(5)
NameError: name 'FunY' is not defined # 名称错误:FunY没有被定义!
这个报错信息中,可以知道FunY函数没有被定义,因为前面的代码中定义的是FunX函数,FunY函数是它的子函数,所以如果不调用FunX函数是无法调用FunY函数的。
页: [1]
查看完整版本: 根据返回的错误提示,FunY到底是函数还是变量名?