回答(16)
2 years ago
你可以使用我古老的Bunch食谱,但如果你不想制作一个"bunch class",Python中已经存在一个非常简单的 - 所有函数都可以有任意属性(包括lambda函数) . 所以,以下工作:
obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')
与古老的 Bunch 食谱相比,是否会失去清晰度是一种风格决定,我当然会留给你 .
2 years ago
内置的 object 可以实例化,但可以 __dict__ 来保存属性 .
我通常只是这样做:
class Object(object):
pass
a = Object()
a.somefield = somevalue
当我可以的时候,我给 Object 类一个更有意义的名字,这取决于我放入的数据类型 .
有些人做了不同的事情,他们使用 dict 的子类,允许属性访问获取键 . ( d.key 而不是 d['key'] )
Edit :对于您的问题的补充,使用 setattr 就可以了 . 你不能在 object() 实例上使用 setattr .
params = ['attr1', 'attr2', 'attr3']
for p in params:
setattr(obj.a, p, value)
2 years ago
obj = someobject
obj.a = SimpleNamespace()
for p in params:
setattr(obj.a, p, value)
# obj.a.attr1
2 years ago
有几种方法可以实现这一目标 . 基本上你需要一个可扩展的对象 .
obj.a = type('Test', (object,), {})
obj.a.b = 'fun'
obj.b = lambda:None
class Test:
pass
obj.c = Test()
2 years ago
现在你可以做(不确定它是否与evilpie一样):
MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42
2 years ago
mock 模块基本上是为此而制作的 .
import mock
obj = mock.Mock()
obj.a = 5
2 years ago
请尝试以下代码:
$ python
>>> class Container(object):
... pass
...
>>> x = Container()
>>> x.a = 10
>>> x.b = 20
>>> x.banana = 100
>>> x.a, x.b, x.banana
(10, 20, 100)
>>> dir(x)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana']
2 years ago
注意:对象没有__dict__,因此您无法将任意属性分配给对象类的实例 .
你可以使用虚拟类实例 .
2 years ago
您也可以直接使用类对象;它创建一个命名空间:
class a: pass
a.somefield1 = 'somevalue1'
setattr(a, 'somefield2', 'somevalue2')
2 years ago
这些解决方案在测试期间非常有用 . 基于其他人的答案我在Python 2.7.9中这样做(没有staticmethod我得到一个TypeError(未绑定的方法......):
In [11]: auth = type('', (), {})
In [12]: auth.func = staticmethod(lambda i: i * 2)
In [13]: auth.func(2)
Out[13]: 4
2 years ago
你使用的是哪些物品?刚尝试使用示例类,它运行良好:
class MyClass:
i = 123456
def f(self):
return "hello world"
b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test
我得到了 123 作为答案 .
我看到这种失败的唯一情况是你在内置对象上尝试 setattr .
2 years ago
在这一天晚些时候来到这里,但是我的pennyworth有一个对象恰好在应用程序中保留了一些有用的路径,但你可以调整它以适应任何你想要使用getattr和点符号访问的信息分类 . (这是我认为这个问题的真正含义):
import os
def x_path(path_name):
return getattr(x_path, path_name)
x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
setattr(x_path, name, os.path.join(x_path.root, name))
这很酷,因为现在:
In [1]: x_path.projects
Out[1]: '/home/x/projects'
In [2]: x_path('caches')
Out[2]: '/home/x/caches'
所以这就像上面的答案一样使用函数对象,但是使用函数来获取值(如果你愿意,你仍然可以使用 (getattr, x_path, 'repository') 而不是 x_path('repository') ) .
2 years ago
如果我们可以在创建嵌套对象之前确定并聚合所有属性和值,那么我们可以创建一个新的类,它在创建时接受字典参数 .
# python 2.7
class NestedObject():
def __init__(self, initial_attrs):
for key in initial_attrs:
setattr(self, key, initial_attrs[key])
obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'
我们还可以允许关键字参数 . 见this post .
class NestedObject(object):
def __init__(self, *initial_attrs, **kwargs):
for dictionary in initial_attrs:
for key in dictionary:
setattr(self, key, dictionary[key])
for key in kwargs:
setattr(self, key, kwargs[key])
obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')
2 years ago
di = {}
for x in range(20):
name = '_id%s' % x
di[name] = type(name, (object), {})
setattr(di[name], "attr", "value")
2 years ago
我这样看的其他方式:
import maya.cmds
def getData(objets=None, attrs=None):
di = {}
for obj in objets:
name = str(obj)
di[name]=[]
for at in attrs:
di[name].append(cmds.getAttr(name+'.'+at)[0])
return di
acns=cmds.ls('L_vest_*_',type='aimConstraint')
attrs=['offset','aimVector','upVector','worldUpVector']
getData(acns,attrs)
2 years ago
这一切都在docs .
TLDR:你需要断言mock的 return_value 属性,其余的是'Magic' .
例:
SomeConstructor = MagicMock()
SomeConstructor.return_value. \
some_class_method.assert_called_once_with('cool!')
SomeConstructor.return_value. \
some_inner_property. \
some_inner_method.assert_called_once_with('super cool!')