python动态设置非实例类属性
我正在尝试动态添加类属性,但不是在实例级别。例如,我可以手动执行以下操作:
class Foo(object):
a = 1
b = 2
c = 3
我希望能够执行以下操作:
class Foo(object):
dct = {'a' : 1, 'b' : 2, 'c' : 3}
for key, val in dct.items():
<update the Foo namespace here>
我希望能够在不从类外部调用类的情况下执行此操作(因此它是可移植的),或者不需要其他类/装饰者。这可能吗?
I am trying to add class attributes dynamically, but not at the instance level. E.g. what I can do manually as:
class Foo(object):
a = 1
b = 2
c = 3
I'd like to be able to do with:
class Foo(object):
dct = {'a' : 1, 'b' : 2, 'c' : 3}
for key, val in dct.items():
<update the Foo namespace here>
I'd like to be able to do this without a call to the class from outside the class (so it's portable), or without additional classes/decorators. Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从您的示例代码来看,您希望在创建类的同时执行此操作。在本例中,假设您使用的是 CPython,则可以使用
locals()
。这是有效的,因为在定义类时,
locals()
引用类名称空间。它是特定于实现的行为,可能不适用于更高版本的 Python 或替代实现。下面显示了一个使用类工厂的不太脏的版本。基本思想是,通过
type()
构造函数将字典转换为类,然后将其用作新类的基类。为了方便使用最少的语法定义属性,我使用了**
约定来接受属性。这实际上只是您自己调用
type()
的语法糖。这工作得很好,例如:Judging from your example code, you want to do this at the same time you create the class. In this case, assuming you're using CPython, you can use
locals()
.This works because while a class is being defined,
locals()
refers to the class namespace. It's implementation-specific behavior and may not work in later versions of Python or alternative implementations.A less dirty-hacky version that uses a class factory is shown below. The basic idea is that your dictionary is converted to a class by way of the
type()
constructor, and this is then used as the base class for your new class. For convenience of defining attributes with a minimum of syntax, I have used the**
convention to accept the attributes.This is really just syntactic sugar for calling
type()
yourself. This works fine, for instance:你的意思是这样的吗:
然后就去
这行得通,因为类也只是一个对象;)
如果你想将所有东西移到类中,那么试试这个:
这将创建一个新类,其中的成员位于
dct
,但所有其他属性都不会出现 - 所以,您想要更改type
的最后一个参数以包含您想要的内容。我在这里找到了如何执行此操作: 什么是 Python 中的元类?Do you mean something like this:
Then just go
This works, because a class is just an object too ;)
If you want to move everything into the class, then try this:
This will create a new class, with the members in
dct
, but all other attributes will not be present - so, you want to alter the last argument totype
to include the stuff you want. I found out how to do this here: What is a metaclass in Python?接受的答案是一个很好的方法。然而,一个缺点是您最终会在 MRO 继承链中得到一个额外的父对象,这并不是真正必要的,甚至可能会令人困惑:
另一种方法是使用装饰器。像这样:
通过这种方式,您可以避免继承链中出现额外的对象。
@decorator
语法只是一种漂亮的表达方式:The accepted answer is a nice approach. However, one downside is you end up with an additional parent object in the MRO inheritance chain that isn't really necessary and might even be confusing:
Another approach would be to use a decorator. Like so:
In this way, you avoid an additional object in the inheritance chain. The
@decorator
syntax is just a pretty way of saying: