c z*_*c z 0 python class python-3.x
def myfn():
class MyClass:
pass
return MyClass()
a = myfn()
b = myfn()
print(type(a) is type(b))
Run Code Online (Sandbox Code Playgroud)
在这里我们可以看到type(a) 不是 type(b).这总是保证是这样的吗?为什么解释器不优化这个,因为定义MyClass不依赖于传递给的任何参数myfn?
该class语句在执行时始终会创建一个新的类对象.课程不是单身人士.通过将class语句放在函数中,只需让您多次执行它.
模块级别的类语句只执行一次,因为模块在首次导入时只执行一次.
你可以通过从sys.modules结构中删除模块对象来绕过这个; 你会注意到Foo我们删除模块后第三次导入的类是另一个对象:
>>> with open('demomodule.py', 'w') as demomodule:
... demomodule.write('class Foo: pass\n')
...
16
>>> import sys
>>> from demomodule import Foo # first import
>>> id(Foo)
140579578254536
>>> import demomodule # just another reference, module is not run again
>>> id(demomodule.Foo)
140579578254536
>>> del sys.modules['demomodule'] # removing the module object
>>> import demomodule # this causes it to be imported again
>>> id(demomodule.Foo)
140579574812488
Run Code Online (Sandbox Code Playgroud)
当您以脚本运行模块然后导入相同的模块时,会发生同样的情况import; 脚本作为__main__模块运行,使用再次import导入脚本然后还为导入的名称创建单独的模块对象:
$ echo 'class Foo: pass
> import demomodule
> print(__name__, id(Foo), id(demomodule.Foo))
> ' > demomodule.py
$ python demomodule.py
demomodule 140718182184264 140718182184264
__main__ 140718182074440 140718182184264
Run Code Online (Sandbox Code Playgroud)
Python本质上是高度动态的; 应用优化(例如缓存由函数生成的类对象)充满了问题.您的功能可能不会采用任何参数,但它不是在真空中运行.例如,我可以替换__build_class__钩子函数并将一个额外的类插入到Python中任何位置创建的任何类的基础中:
>>> def foo_class():
... class Foo: pass
... return Foo
...
>>> foo_class().__mro__
(<class '__main__.foo_class.<locals>.Foo'>, <class 'object'>)
>>> import builtins
>>> class Bar: pass
>>> orig_buildclass = builtins.__build_class__
>>> def my_buildclass(f, name, *bases, **kwargs):
... return orig_buildclass(f, name, *((Bar,) + bases), **kwargs)
...
>>> builtins.__build_class__ = my_buildclass
>>> foo_class().__mro__
(<class '__main__.foo_class.<locals>.Foo'>, <class '__main__.Bar'>, <class 'object'>)
Run Code Online (Sandbox Code Playgroud)
Python充满了像这样的钩子.
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |