Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在声明类属性时触发setter?_Python - Fatal编程技术网

Python 如何在声明类属性时触发setter?

Python 如何在声明类属性时触发setter?,python,Python,我有一节课;我们叫它福吧。它有一个键类型类属性,该属性包含一个类型: 课程编号:pass Foo类: 钥匙类型=钥匙 我想在密钥类型初始化*时以及在它更改时对其运行一些方法 所以我在元类中设置了key_type属性: 课程编号:pass 类OtherKey:通过 类元类型: _键类型=无 @财产 def钥匙类型CLS: 返回cls.\u键\u类型 @按键式设定器 def键类型CLS,值: printf'将键类型设置为{value}' cls.\u键\u类型=值 类Foometaclass=Met

我有一节课;我们叫它福吧。它有一个键类型类属性,该属性包含一个类型:

课程编号:pass Foo类: 钥匙类型=钥匙 我想在密钥类型初始化*时以及在它更改时对其运行一些方法

所以我在元类中设置了key_type属性:

课程编号:pass 类OtherKey:通过 类元类型: _键类型=无 @财产 def钥匙类型CLS: 返回cls.\u键\u类型 @按键式设定器 def键类型CLS,值: printf'将键类型设置为{value}' cls.\u键\u类型=值 类Foometaclass=MetaFoo: 钥匙类型=钥匙 如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: printfoo的键类型:{Foo.key_type} Foo.key\u type=OtherKey printfoo的键类型:{Foo.key_type} 输出:

Foo的密钥类型:无 将按键类型设置为 Foo的密钥类型: 似乎元类中的_key_type的定义超过了主类中的key_type的定义。但最重要的是,setter不是用键类型调用的

预期产出:

将按键类型设置为 Foo的密钥类型: 将按键类型设置为 Foo的密钥类型: *我还希望它在初始化时发生的原因是Foo可以从中继承。我想知道是在MetaFoo中还是在Foo中,一个子类是否使用了不同的键类型。

Foo类中键类型的定义实际上在第三个参数中添加了一个键值对,该参数是MetaFoo初始化的dict,它不会做任何其他事情

因此,您可以操纵MetaFoo的初始化来显式调用setter方法。这可以通过重写元类的_init__方法来实现:

课程编号:pass 类OtherKey:通过 类元类型: _键类型=无 @财产 def钥匙类型CLS: 返回cls.\u键\u类型 @按键式设定器 def键类型CLS,值: printf'将键类型设置为{value}' cls.\u键\u类型=值 定义初始值、名称、基数、千瓦: 超级美泰,自我。初始名称,基地,千瓦 对于键,val(千瓦)项目: setattrself,key,val 类Foometaclass=MetaFoo: 钥匙类型=钥匙 如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: printfoo的键类型:{Foo.key_type} Foo.key\u type=OtherKey printfoo的键类型:{Foo.key_type} 输出:

将按键类型设置为 Foo的密钥类型: 将按键类型设置为 Foo的密钥类型: 类Foo中key_type的定义实际上在第三个参数中添加了一个键值对,该参数是MetaFoo初始化的dict,除此之外它不会做任何事情

因此,您可以操纵MetaFoo的初始化来显式调用setter方法。这可以通过重写元类的_init__方法来实现:

课程编号:pass 类OtherKey:通过 类元类型: _键类型=无 @财产 def钥匙类型CLS: 返回cls.\u键\u类型 @按键式设定器 def键类型CLS,值: printf'将键类型设置为{value}' cls.\u键\u类型=值 定义初始值、名称、基数、千瓦: 超级美泰,自我。初始名称,基地,千瓦 对于键,val(千瓦)项目: setattrself,key,val 类Foometaclass=MetaFoo: 钥匙类型=钥匙 如果uuuu name uuuuu==\uuuuuuuu main\uuuuuuuu: printfoo的键类型:{Foo.key_type} Foo.key\u type=OtherKey printfoo的键类型:{Foo.key_type} 输出:

将按键类型设置为 Foo的密钥类型: 将按键类型设置为 Foo的密钥类型:
请注意,类主体指定给临时类命名空间。您可能需要检查是否实际分配了馈送到类型为的命名空间的键。_prepare__;而不仅仅是复制;对key_type的初始赋值发生在元类实例出现之前,即类Foo具有属性。您只是分配给一个名称,该名称将在调用元类后成为属性。请注意,类主体分配给一个临时类命名空间。您可能需要检查是否实际分配了馈送到类型为的命名空间的键。_prepare__;而不仅仅是复制;对key_type的初始赋值发生在元类实例出现之前,即类Foo具有属性。您只需指定一个名称,该名称将在调用元类后成为属性。