Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有一种方法可以同时设置对象的值和属性?_Python_Python 3.x - Fatal编程技术网

Python 有没有一种方法可以同时设置对象的值和属性?

Python 有没有一种方法可以同时设置对象的值和属性?,python,python-3.x,Python,Python 3.x,问题显示了如何向内置数据类型添加属性。但是,是否有一种方法可以在一个步骤中将属性添加到变量中,以便在函数调用中使用它,相当于以下内容: >>> class Adict(dict): pass >>> def myfunc(x): print(x, x.my_attr) >>> v = {'a':'cat'} >>> var = Adict(v) >>> var.my_at

问题显示了如何向内置数据类型添加属性。但是,是否有一种方法可以在一个步骤中将属性添加到变量中,以便在函数调用中使用它,相当于以下内容:

>>> class Adict(dict):
        pass

>>> def myfunc(x):
        print(x, x.my_attr)

>>> v = {'a':'cat'}
>>> var = Adict(v)
>>> var.my_attr = 'whatever'
>>> myfunc(var)
{'a': 'cat'} whatever
我想将最后3行缩减为一行,类似于:

>>> myfunc(Adict(v, my_attr='whatever'))
它传递一个包含两个项(“a”和“my_attr”)且没有属性的字典,或者

>>> myfunc(Adict(v).my_attr='whatever')
它被解析为关键字参数而不是属性设置。有没有一种方法可以在单个步骤中设置值和属性

--------编辑----------

为了回答Sven的问题,我正在扩展优秀的JSON模式处理器,其中包括以下代码:

    # parse properties and add them individually
    for prop, val in schema.items():
        if prop == 'type':
            self._add_type(val)
        elif prop == 'required':
            self._add_required(val)
        elif prop in ['properties', 'patternProperties']:
            v = Adict(val)
            v._ptype = prop
            self._add_properties(v, 'add_schema')
        elif prop == 'items':
            self._add_items(val, 'add_schema')
        elif prop not in self._other:
            self._other[prop] = val

我不需要自定义dict有任何特殊功能,只需要能够用属性标记它,并且能够清理
properties
下的3行代码就好了,这样它就可以直观地匹配其他情况:-)。相反,我可能会将该标记单独传递给
self.\u add\u properties()
函数。

您可以覆盖
Adict
的构造函数以接受关键字参数并基于它设置属性:

class Adict(dict):
    def __init__(*args, my_attr=None, **kwargs):
        self = args[0]
        self.my_attr = my_attr
        dict.__init__(*args, **kwargs)

这将为您提供一个以某种奇怪的方式更改的词典,因为
my_attr
关键字参数的行为将不同于所有其他关键字参数。(您也可以选择不将
kwargs
传递给
dict
构造函数。)

您可以引入所谓的构建器(或类工厂模式),它获取所有必要的参数并返回结果对象。这是你想要的吗

class Adict(dict):
    pass

def myfunc(x):
    print(x, x.my_attr)

def my_builder(v, **kvargs):
    obj = Adict(v)
    obj.__dict__.update(kvargs)  # internal dictionary with attributes
    return obj                   # return the created object

# Your original code.    
v = {'a':'cat'}
var = Adict(v)
var.my_attr = 'whatever'
myfunc(var)

print('------------')

v2 = {'d': 'dog'}
myfunc(my_builder(v2, my_attr='whatever_dog'))

print('------------')

myfunc(my_builder({'c': 'crocodile'}, my_attr='whatever_croc'))

这是一种非常简单的方法,可以精确地完成您在三行中所做的操作。然而,建设者以后可能会聪明得多。它可以测试参数的值和类型,并根据情况创建、初始化和返回其他类型的对象。这就是类工厂模式的设计目的——为您完成工作的代理。(这里的问题是,在执行
myfunc()
之后,您将抛出
obj
,但您可能想对该对象执行其他操作—将其传递到某个地方或其他任何地方。)

让我们重新启动。这句话{'a':'cat'}无论什么东西都会把我甩了。你能解释一下这到底是什么吗?将这些信息作为属性添加到值中是一种相当少见的方法。使用单独的参数似乎要好得多,甚至可以使用单独的函数。(这两个函数可以调用引擎盖下的公共辅助函数。)
genson
数据结构嵌套到任意深度并递归处理。我需要一种方法来处理,例如,一个dict-of-dict-of-dict-of-list-of-dict,同时跟踪每个dict的类型(独立或合并)。属性(如getattr()中的属性)似乎是在每个dict上标记类型的最直接的方法,即使它不常见。在JSON术语中,“属性”是dict的键/值,因此在dict上附加一个标记而不添加键/值是目标。谢谢,但是如果没有Pythonic的“non-wierd”语法,我只需要在程序中添加额外的行。三行文字更容易阅读,但我希望有一个简洁的习惯用法。@Dave在字典中添加自定义属性是很少见的事情。如果您需要类似的东西,您通常希望使用自定义类,而不是内置字典,因此编写自定义构造函数将是一种方法。这变得奇怪的唯一原因是我试图使自定义类尽可能与内置dict兼容。也许你可以提供一些你想要达到的目标的背景。太好了!学习新的设计模式总是很好的。现在我所需要做的就是研究魔法
obj.\uuu dict\uuu.update()
咒语。
\uuu dict\uuu
属性是每个对象的内部字典。它保留了属于对象的所有属性,这些属性对于类/对象的基本功能来说是不固定的。这意味着任何变量或方法名称都存储在这里,并且该值是该字典项的值部分。
.update()
是一个字典方法,它使用参数字典的内容更新字典。
**kvargs
是一个由键/值参数构建的字典。