鱼C论坛

 找回密码
 立即注册
查看: 2121|回复: 10

[已解决]请问为啥wrapper后面不是要求两个参数吗?test1一个a也行的啊。??

[复制链接]
发表于 2021-7-12 22:01:27 | 显示全部楼层 |阅读模式
8鱼币
>>> def log(func):
    def wrapper(*args,**kwargs):
        print('log开始 ...')
        ret = func(*args,**kwargs)
        print('log结束 ...')
        return ret
    return wrapper


@log
def test1(a):
    print('test1 ..', a)
    return a


def test2():
    print('test2 ..')

print(test1.__name__)
print(test2.__name__)
最佳答案
2021-7-12 22:01:28
本帖最后由 阿奇_o 于 2021-7-13 16:08 编辑
杨东明 发表于 2021-7-13 09:45
类不是class定义吗?wrapper不是函数吗。。还有就是第10行的@修饰符下的test1()函数是不是被修饰函数, ...


准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括
definition.__name__
The name of the class, function, method, descriptor, or generator instance.
导入时,才是指“模块名”,
__name__
The __name__ attribute must be set to the fully-qualified name of the module. This name is used to uniquely identify the module in the import system.


换言之,可以看做是 当前命名空间的唯一标识符(独一无二的一个名字),使用 globals() 查看,就明白了:
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'log': <function log at 0x0000026960AD19D8>, 'test1': <function log.<locals>.wrapper at 0x0000026960ADF9D8>, 'test2': <function test2 at 0x0000026960B27DC8>}

可以看到,被@log修饰的test1函数,指向的是 (作为) 函数log的一个局部变量 : log.<locals>.wrapper
当你用 print(test1.__name__) 时,它 只打印了 wrapper 这个变量名。
(又或者说,这里print其实是 调用用了 log.<locals>.wrapper.__str__() 其返回的字符串,刚好是 wrapper。 若是自定义的类,你其实可以重写__str__,就可以返回任何字符串...)
>>> class MyClass():
        def __str__(self):
                return '我叫MyClass'
>>> obj = MyClass()
>>> print(obj)
我叫MyClass
>>> obj.__str__()
'我叫MyClass'
>>> 



OK,应该可以明白了。。

至于 参数个数的问题,是python的语法特性,* 代表若干个(0-N个参数,皆可)具体Twilight大佬已经解释了。

最佳答案

查看完整内容

准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括 换言之,可以看做是 当前命名空间的唯一标识符(独一无二的一个名字),使用 globals() 查看,就明白了: OK,应该可以明白了。。 至于 参数个数的问题,是python的语法特性,* 代表若干个(0-N个参数,皆可)具体Twilight大佬已经解释了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-12 22:01:28 | 显示全部楼层    本楼为最佳答案   
本帖最后由 阿奇_o 于 2021-7-13 16:08 编辑
杨东明 发表于 2021-7-13 09:45
类不是class定义吗?wrapper不是函数吗。。还有就是第10行的@修饰符下的test1()函数是不是被修饰函数, ...


准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括
definition.__name__
The name of the class, function, method, descriptor, or generator instance.
导入时,才是指“模块名”,
__name__
The __name__ attribute must be set to the fully-qualified name of the module. This name is used to uniquely identify the module in the import system.


换言之,可以看做是 当前命名空间的唯一标识符(独一无二的一个名字),使用 globals() 查看,就明白了:
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'log': <function log at 0x0000026960AD19D8>, 'test1': <function log.<locals>.wrapper at 0x0000026960ADF9D8>, 'test2': <function test2 at 0x0000026960B27DC8>}

可以看到,被@log修饰的test1函数,指向的是 (作为) 函数log的一个局部变量 : log.<locals>.wrapper
当你用 print(test1.__name__) 时,它 只打印了 wrapper 这个变量名。
(又或者说,这里print其实是 调用用了 log.<locals>.wrapper.__str__() 其返回的字符串,刚好是 wrapper。 若是自定义的类,你其实可以重写__str__,就可以返回任何字符串...)
>>> class MyClass():
        def __str__(self):
                return '我叫MyClass'
>>> obj = MyClass()
>>> print(obj)
我叫MyClass
>>> obj.__str__()
'我叫MyClass'
>>> 



OK,应该可以明白了。。

至于 参数个数的问题,是python的语法特性,* 代表若干个(0-N个参数,皆可)具体Twilight大佬已经解释了。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-12 22:04:08 | 显示全部楼层
还有就是19行test1.__name__不是只会返回函数名test1或者‘main’吗?没懂为啥会返回wrapper

运行结果:wrapper
               test2
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-12 22:06:27 | 显示全部楼层
第10行的@修饰符下的test1()函数是不是被修饰函数,它是以func = test1(a)的方式传进log函数里面吗?但是没懂为啥wrapper两个参数,test1一个参数也可以??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-13 01:49:22 | 显示全部楼层
杨东明 发表于 2021-7-12 22:04
还有就是19行test1.__name__不是只会返回函数名test1或者‘main’吗?没懂为啥会返回wrapper

运行结果: ...


请问为啥wrapper后面不是要求两个参数吗?


*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多

**参数 是表示收集参数成字典,也可以 0 ~ 理论无穷多

关键字参数必须位于位置参数之后,这里 字典收集参数必须为关键字参数

__name__不是只会返回函数名test1或者‘main’吗?


__name__ 是返回此时运行对象的程序模块名,而每一个 Python 的类都能当成模块,所以这里返回 wrapper

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-13 09:45:32 | 显示全部楼层
Twilight6 发表于 2021-7-13 01:49
*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多

**参数 是表示收集参数成字典,也可以 0 ~  ...

类不是class定义吗?wrapper不是函数吗。。还有就是第10行的@修饰符下的test1()函数是不是被修饰函数,它是以func = test1(a)的方式传进log函数里面吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-13 16:27:06 | 显示全部楼层
阿奇_o 发表于 2021-7-13 15:52
准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括

谢谢,懂了些了,我想再问问你写的代码,第7行有时候我看定义类后面不需要加(),我想问问这儿加与不加有什么含义吗??还有就是第11行我敲了一下代码,为啥我的运行打印的是   <__main__.B object at 0x00000139ADFD1D88>
代码是:
>>> class B():
        def str(self):
                return '你好'

        
>>> b = B()
>>> print (b)
<__main__.B object at 0x00000139ADFD1D88>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-13 16:32:44 | 显示全部楼层
阿奇_o 发表于 2021-7-13 15:52
准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括

再问问print (b)后打印的 __main__.B object at 0x00000139ADFD1D88 ,这个__main__是啥意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-13 18:55:23 | 显示全部楼层
本帖最后由 阿奇_o 于 2021-7-13 19:04 编辑
杨东明 发表于 2021-7-13 16:27
谢谢,懂了些了,我想再问问你写的代码,第7行有时候我看定义类后面不需要加(),我想问问这儿加与不加 ...


是 __str__(self) ,不是 str(self),  这些双下划线的 都是Python的 “特殊方法”。 有特殊的用处,涉及数据结构、对象运算等等。
至于 类名后 加不加 ()  ,都可以,若要指定继承父类,就要加(默认其实都继承object类,不用写)。。。 这些都是小语法、小细节,不重要。。。
又因为 __str__这特殊方法在object这总父类里肯定有,你没有在子类里 正确重写 __str__ , 那它就往上找,调用了 总父类的object的 __str__ , 其默认 返回啥,就是啥。。。

嗯,看来你,面向对象部分,也不太了解,可以先去 菜鸟教程或w3cshool等网站,先看看简单的OOP例子。


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-13 20:51:15 | 显示全部楼层
阿奇_o 发表于 2021-7-13 15:52
准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括

谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-13 20:51:54 | 显示全部楼层
Twilight6 发表于 2021-7-13 01:49
*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多

**参数 是表示收集参数成字典,也可以 0 ~  ...

谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 03:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表