请问为啥wrapper后面不是要求两个参数吗?test1一个a也行的啊。??
>>> 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__) 本帖最后由 阿奇_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大佬已经解释了。
还有就是19行test1.__name__不是只会返回函数名test1或者‘main’吗?没懂为啥会返回wrapper
运行结果:wrapper
test2 第10行的@修饰符下的test1()函数是不是被修饰函数,它是以func = test1(a)的方式传进log函数里面吗?但是没懂为啥wrapper两个参数,test1一个参数也可以?? 杨东明 发表于 2021-7-12 22:04
还有就是19行test1.__name__不是只会返回函数名test1或者‘main’吗?没懂为啥会返回wrapper
运行结果: ...
请问为啥wrapper后面不是要求两个参数吗?
*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多
**参数 是表示收集参数成字典,也可以 0 ~ 理论无穷多
关键字参数必须位于位置参数之后,这里 字典收集参数必须为关键字参数
__name__不是只会返回函数名test1或者‘main’吗?
__name__ 是返回此时运行对象的程序模块名,而每一个 Python 的类都能当成模块,所以这里返回 wrapper
Twilight6 发表于 2021-7-13 01:49
*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多
**参数 是表示收集参数成字典,也可以 0 ~...
类不是class定义吗?wrapper不是函数吗。。还有就是第10行的@修饰符下的test1()函数是不是被修饰函数,它是以func = test1(a)的方式传进log函数里面吗? 阿奇_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> 阿奇_o 发表于 2021-7-13 15:52
准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括
再问问print (b)后打印的 __main__.B object at 0x00000139ADFD1D88 ,这个__main__是啥意思{:9_240:} 本帖最后由 阿奇_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例子。
阿奇_o 发表于 2021-7-13 15:52
准确来说,__name__ 应该不仅仅包括 “模块名”或“类名”,而是 包括
谢谢{:9_231:} Twilight6 发表于 2021-7-13 01:49
*参数 是表示收集参数成元组,可以 0 ~ 理论无穷多
**参数 是表示收集参数成字典,也可以 0 ~...
谢谢{:9_231:}
页:
[1]