我找不到一个简短的构造函数调用的引用,它会初始化调用者选择的变量。我在寻找
class AClass:
def __init__(self):
pass
instance = AClass(var1=3, var2=5)
而不是写较重的
class AClass:
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
或更重的
instance = AClass()
instance.var1 = 3
instance.var2 = 5
我错过了什么吗?
答案 0 :(得分:5)
您可以直接更新对象的__dict__
属性,即属性存储的位置
class AClass:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
c = AClass(var1=1, var2='a')
答案 1 :(得分:4)
这是一个很好的问题,对我来说也是一个难题。
在现代Python世界中,有三个(优秀)速记初始化器(这个术语很聪明,我采用它),根据您的需要。 无需使用__init__
方法进行任何步法(这是您首先想要避免的)。
命名空间对象
如果您希望为实例分配任意值(即不由类强制执行),则应使用名为命名空间的特定数据结构。命名空间对象是可以使用点表示法访问的对象,您可以基本上为其分配所需的内容。
您可以从argparse导入Namespace类(这里介绍:How do I create a Python namespace (argparse.parse_args value)?)。从Python 3.3开始。标准类型包中提供了SimpleNamespace类。
from types import SimpleNamespace
instance = SimpleNamespace(var1=var1, var2=var2)
你也可以写:
instance = SimpleNamespace()
instance.var1 = var1
instance.var2 = var2
让我们说它是“快速而肮脏的方式”,它可以在许多情况下起作用。一般来说,甚至没有必要申报你的班级。
如果您希望实例仍然有一些方法和属性,您仍然可以这样做:
class AClass(Namespace):
def mymethod(self, ...):
pass
然后:
instance = AClass(var1=var1, var2=var2, etc.)
这为您提供了最大的灵活性。
命名元组
另一方面,如果您希望课程强制这些属性,那么您还有另一个更可靠的选项。
命名的元组生成不可变实例,这些实例一次性初始化。将它们视为普通元组,但每个项目也可以用点符号访问。这个类namedtuple是Python标准发行版的一部分。这就是你如何生成你的课程:
from collections import namedtuple
AClass = namedtuple("AClass", "var1 var2")
请注意定义有多酷和短,而不需要__init__
方法。之后你可以完成课程。
创建一个对象:
instance = AClass(var1, var2)
或
instance = AClass(var1=var1, var2=var2)
命名列表
但是,如果您希望该实例是可变的,即允许您更新实例的属性,该怎么办?答案是命名列表(也称为RecordClass)。从概念上讲,它就像一个普通的列表,其中的项目也可以用点表示法访问。
有各种各样的实现。我个人使用名称恰当的namedlist。
语法相同:
from namedlist import namedlist
AClass = namedlist("AClass", "var1 var2")
创建一个对象:
instance = AClass(var1, var2)
或:
instance = AClass(var1=var1, var2=var2)
然后你可以修改它们:
instance.var1 = var3
但您无法添加未定义的属性。
>>> instance.var4 = var4
File "<stdin>", line 1, in <module>
AttributeError: 'instance' object has no attribute 'var4'
<强>用法强>
这是我的两位:
命名空间对象是为了获得最大的灵活性,甚至不需要声明一个类;存在不正常行为的风险(但Python是同意成人的语言)。如果您只有一个实例和/或您知道自己在做什么,那将是最佳选择。
namedtuple 类生成器非常适合生成函数返回的对象(请参阅Raymond Hettinger讲座中的brief explanation)。返回的元组不是返回用户需要在文档中查找的平淡元组,而是不言自明(dir或help会执行此操作)。并且它无论如何都与元组使用兼容(例如k,v, z = my_func()
)。而且它是不可变的,它有自己的优势。
namedlist 类生成器在各种情况下都很有用,包括当你需要从函数返回多个值时,需要在稍后阶段进行修改(和你一样)仍然可以打开它们:k, v, z = instance
)。如果您需要具有强制属性的适当类的可变对象,那么这可能是首选解决方案。
如果使用得当,这可能会大大减少编写类和处理实例所花费的时间!
答案 2 :(得分:1)
您可以使用对象属性的字典表示,并使用给予构造函数的关键字参数更新其元素:
class AClass:
def __init__(self, **kwargs):
self.__dict__.update(**kwargs)
instance = AClass(var1=3, var2=5)
print(instance.var1, instance.var2) # prints 3 5
但是,考虑一下这种风格,考虑this question及其答案。除非你知道自己在做什么,否则最好一个一个地明确设置参数。对于你和其他人来说,这将更容易理解 - 明确比隐含更好。如果您使用__dict__.update
方式,请正确记录。
答案 3 :(得分:-2)
尝试
class AClass:
def __init__(self, **vars):
self.var1 = vars.get('var1')