python类定义默认值为none_python-将类变量作为默认值分配给类方法参数

这是一个简单示例模块的代码分解。 代码对象是字节码,其使用的常量和名称以及有关局部变量数量,所需堆栈大小等的元数据的只读容器。请注意,所有代码对象均被编译为常量。 这些是在编译时创建的。 但是对象__init__.__code__和__defaults__在执行时实例化(例如,在导入模块时)。

为了创建该类,__init__.__code__使用名称__defaults__,基数'Cl' default和__init__包含类名称空间的属性。 这就像通过调用self手动实例化类型。要生成dict,要从代码对象A创建一个函数,然后调用该函数。 最后,类对象通过STORE_NAME存储在模块名称空间中。

在代码对象__init__.__code__中,将__defaults__作为'Cl'的参数加载到堆栈上。字节码op default将在当前本地语言(即定义的类名称空间),模块全局变量和内置插件中搜索__init__。 如果未在global或buildins范围内定义self,则此操作显然将失败。 它显然不在本地范围内定义。

但是,如果确实成功,将使用__init__.__code__属性作为其__defaults__属性创建该函数,然后将其存储为本地名称'Cl'。

>>> code = compile('''

... class A(object):

... def test(self, a=self.z): pass

... ''', '', 'exec')

>>> dis.dis(code)

2 0 LOAD_CONST 0 ('A')

3 LOAD_NAME 0 (object)

6 BUILD_TUPLE 1

9 LOAD_CONST 1 ()

12 MAKE_FUNCTION 0

15 CALL_FUNCTION 0

18 BUILD_CLASS

19 STORE_NAME 1 (A)

22 LOAD_CONST 2 (None)

25 RETURN_VALUE

>>> dis.dis(code.co_consts[1]) # code object A

2 0 LOAD_NAME 0 (__name__)

3 STORE_NAME 1 (__module__)

3 6 LOAD_NAME 2 (self)

9 LOAD_ATTR 3 (z)

12 LOAD_CONST 0 ()

15 MAKE_FUNCTION 1

18 STORE_NAME 4 (test)

21 LOAD_LOCALS

22 RETURN_VALUE

@uselpa:您的pastebin示例(为2.x重写):

>>> code = compile('''

... default = 1

... class Cl(object):

... def __init__(self, a=default):

... print a

... Cl()

... default = 2

... Cl()

... ''', '', 'exec')

>>> dis.dis(code)

2 0 LOAD_CONST 0 (1)

3 STORE_NAME 0 (default)

3 6 LOAD_CONST 1 ('Cl')

9 LOAD_NAME 1 (object)

12 BUILD_TUPLE 1

15 LOAD_CONST 2 ()

18 MAKE_FUNCTION 0

21 CALL_FUNCTION 0

24 BUILD_CLASS

25 STORE_NAME 2 (Cl)

6 28 LOAD_NAME 2 (Cl)

31 CALL_FUNCTION 0

34 POP_TOP

7 35 LOAD_CONST 3 (2)

38 STORE_NAME 0 (default)

8 41 LOAD_NAME 2 (Cl)

44 CALL_FUNCTION 0

47 POP_TOP

48 LOAD_CONST 4 (None)

51 RETURN_VALUE

如您所见,类对象__init__.__code__(和功能对象__defaults__)仅被实例化并存储到本地名称'Cl'。 该模块在运行时按顺序执行,因此随后重新绑定名称default将不会影响__init__中的默认值。

您可以使用先前编译的代码和新的默认值动态实例化一个新函数:

>>> default = 1

>>> class Cl(object):

... def __init__(self, a=default):

... print a

...

>>> from types import FunctionType

>>> default = 2

>>> Cl.__init__ = FunctionType(

... Cl.__init__.__code__, globals(), '__init__', (default,), None)

>>> c = Cl()

2

这将重用__init__.__code__中已编译的代码对象,以创建具有新__defaults__元组的函数:

>>> Cl.__init__.__defaults__

(2,)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值