gpt4 book ai didi

Python - 从动态 attrname 列表在 __init__ 中创建属性

转载 作者:太空宇宙 更新时间:2023-11-04 10:51:53 24 4
gpt4 key购买 nike

我正在编写一些天文馆软件的 Python 插件。这个插件带有访问天文馆软件命名空间内对象的功能,但它们很麻烦而且不是面向对象的。因此,我试图创建一个类来重载属性访问以简化编码。我希望能够做这样的事情,

rocket = RemoteObject('rocket')
rocket.color = blue

将天文馆软件命名空间中火箭对象的颜色设置为蓝色。

How to define properties in __init__非常接近。我遇到的一个困难是我需要在创建实例时确定我的属性的名称。另一个困难是由于我对描述符的一般理解不足:属性调用正在返回或覆盖我的属性对象本身,而不是调用它的 getter 和 setter。

这是我目前所拥有的:

class RemoteObject(object):
def __init__(self,remote_object_name):
self.normalattr = 'foo'
self.normalmethod = lambda: 'spam'
for attrname in get_remote_object_attrnames(remote_object_name):
def _get(self):
return fetch_remote_attr_value(remote_object_name,attrname)
def _set(self,value):
set_remote_attr_value(remote_object_name,attrname,value)
setattr(self,attrname,property(_get,_set))

if __name__ == '__main__':
get_remote_object_attrnames = lambda name: {'apple','banana','cherry'}
fetch_remote_attr_value = lambda o,a: 'Reading %s.%s' % (o,a)
set_remote_attr_value = lambda o,a,v: 'Writing %s.%s = %s' % (o,a,v)

scene = RemoteObject('scene')
for x in scene.__dict__.items(): print x
print '-----'
print scene.normalattr
print scene.normalmethod()
print scene.apple
scene.banana = '42'
print '-----'
for x in scene.__dict__.items(): print x

运行时返回:

('cherry', <property object at 0x00CB65A0>)
('normalmethod', <function <lambda> at 0x00CB8FB0>)
('banana', <property object at 0x00CB65D0>)
('normalattr', 'foo')
('apple', <property object at 0x00CB6600>)
-----
foo
spam
<property object at 0x00CB6600>
-----
('cherry', <property object at 0x00CB65A0>)
('normalmethod', <function <lambda> at 0x00CB8FB0>)
('banana', '42')
('normalattr', 'foo')
('apple', <property object at 0x00CB6600>)

有没有更好的方法来处理需要每个实例属性的动态属性名集?为什么实例属性匹配属性名称返回属性对象本身而不是执行它的 getter 或 setter?

最佳答案

您不能在实例上定义属性; property 对象是描述符,描述符 __get____set__ Hook 仅在类上支持。

您必须在类上定义所有这些属性并禁用它们(可能从禁用的属性中抛出 AttributeError),或者使用 __getattr__ __setattr__ 代替。

“全部定义”方法:

class Foo(object):
__enabled_properties = ()

def __init__(self):
self.__enabled_properties = ('bar',)

@property
def bar(self):
if 'bar' not in self.__enabled_properties:
raise AttributeError('bar')
...

@bar.setter
def bar(self, value):
if 'bar' not in self.__enabled_properties:
raise AttributeError('bar')
...

__getattr____setattr__ 方法:

class Foo(object):
__enabled_properties = ()
__dynamic_properties = ('bar', 'spam', 'eggs')

def __init__(self):
self.__enabled_properties = ('bar',)

def __getattr__(self, attr):
if attr in self.__dynamic_properties:
if attr not in self.__enabled_properties:
raise AttributeError(attr)
# Fetch a remote value here and return it
if attr not in self.__dict__:
raise AttributeError(attr)
return self.__dict__[attr]

def __setattr__(self, attr, value):
if attr in self.__dynamic_properties:
if attr not in self.__enabled_properties:
raise AttributeError(attr)
# Set a remote value here
self.__dict__[attr] = value

关于Python - 从动态 attrname 列表在 __init__ 中创建属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13310696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com