java 创建对象 设置属性_如何创建对象并向其添加属性?

回答(16)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

你可以使用我古老的Bunch食谱,但如果你不想制作一个"bunch class",Python中已经存在一个非常简单的 - 所有函数都可以有任意属性(包括lambda函数) . 所以,以下工作:

obj = someobject

obj.a = lambda: None

setattr(obj.a, 'somefield', 'somevalue')

与古老的 Bunch 食谱相比,是否会失去清晰度是一种风格决定,我当然会留给你 .

e15298c6a3b4591803e154ab0c3b3e2e.png

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)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

obj = someobject

obj.a = SimpleNamespace()

for p in params:

setattr(obj.a, p, value)

# obj.a.attr1

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

有几种方法可以实现这一目标 . 基本上你需要一个可扩展的对象 .

obj.a = type('Test', (object,), {})

obj.a.b = 'fun'

obj.b = lambda:None

class Test:

pass

obj.c = Test()

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

现在你可以做(不确定它是否与evilpie一样):

MyObject = type('MyObject', (object,), {})

obj = MyObject()

obj.value = 42

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

mock 模块基本上是为此而制作的 .

import mock

obj = mock.Mock()

obj.a = 5

e15298c6a3b4591803e154ab0c3b3e2e.png

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']

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

注意:对象没有__dict__,因此您无法将任意属性分配给对象类的实例 .

你可以使用虚拟类实例 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

您也可以直接使用类对象;它创建一个命名空间:

class a: pass

a.somefield1 = 'somevalue1'

setattr(a, 'somefield2', 'somevalue2')

e15298c6a3b4591803e154ab0c3b3e2e.png

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

e15298c6a3b4591803e154ab0c3b3e2e.png

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 .

e15298c6a3b4591803e154ab0c3b3e2e.png

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') ) .

e15298c6a3b4591803e154ab0c3b3e2e.png

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')

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

di = {}

for x in range(20):

name = '_id%s' % x

di[name] = type(name, (object), {})

setattr(di[name], "attr", "value")

e15298c6a3b4591803e154ab0c3b3e2e.png

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)

e15298c6a3b4591803e154ab0c3b3e2e.png

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!')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值