Python 在用户定义类的实例上启用列表(实例)或元组(实例)

Python 在用户定义类的实例上启用列表(实例)或元组(实例),python,Python,是否有一种方法可以使用标准类型构造函数(如int、set、dict、list、tuple等)以用户定义的方式将用户定义类的实例强制为这些类型之一?比如说 class Example: def __init__(self): self.a=1 self.b=2 然后 >>> ex = Example() >>> dict(ex) {"a":1, "b":2} 我不知道这是否可能,如果可能,我需要在类定义中添加什么。现在

是否有一种方法可以使用标准类型构造函数(如int、set、dict、list、tuple等)以用户定义的方式将用户定义类的实例强制为这些类型之一?比如说

class Example:
    def __init__(self):
        self.a=1
        self.b=2
然后

>>> ex = Example()
>>> dict(ex)
{"a":1, "b":2}

我不知道这是否可能,如果可能,我需要在类定义中添加什么。现在我需要这个,我实现了一个as_dict方法,我在对象上调用了它,但它看起来不那么自然。

通过添加一个u iter_u_u方法,使您的类型变得可移植。琐碎地:

class Example:

    def __init__(self):
        self.a = 1
        self.b = 2

    def __iter__(self):
        yield "a", self.a
        yield "b", self.b
这将生成一个包含名称/值对的元组序列,dict很乐意使用这些元组

dict(Example())    # {'a': 1, 'b': 2}
当然,这里有很多重复你自己的话。因此,您可以编写uu iter_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

def __iter__(self):
    names = "a", "b"
    for name in names:
        yield name, getattr(self, name)
def __iter__(self):
    yield from self.__dict__.items()
您还可以让它内省实例中的所有属性,忽略其值可调用的属性:

def __iter__(self):
    names = dir(self)
    for name in names:
        value = getattr(self, name)
        if not callable(value):
             yield name, value
或者让它从实例的_dict________________________________________

def __iter__(self):
    names = "a", "b"
    for name in names:
        yield name, getattr(self, name)
def __iter__(self):
    yield from self.__dict__.items()

通过添加一个_iter__)方法,使您的类型可编辑。琐碎地:

class Example:

    def __init__(self):
        self.a = 1
        self.b = 2

    def __iter__(self):
        yield "a", self.a
        yield "b", self.b
这将生成一个包含名称/值对的元组序列,dict很乐意使用这些元组

dict(Example())    # {'a': 1, 'b': 2}
当然,这里有很多重复你自己的话。因此,您可以编写uu iter_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

def __iter__(self):
    names = "a", "b"
    for name in names:
        yield name, getattr(self, name)
def __iter__(self):
    yield from self.__dict__.items()
您还可以让它内省实例中的所有属性,忽略其值可调用的属性:

def __iter__(self):
    names = dir(self)
    for name in names:
        value = getattr(self, name)
        if not callable(value):
             yield name, value
或者让它从实例的_dict________________________________________

def __iter__(self):
    names = "a", "b"
    for name in names:
        yield name, getattr(self, name)
def __iter__(self):
    yield from self.__dict__.items()

你需要制作你的物品

list和tuple都接受iterable作为参数,它们将重复使用该参数,直到构造新集合为止。为了使您的类能够使用这种机制,您需要根据类的特定语义,至少定义方法,也可能定义方法

您的_iter___)实现将需要返回一个实现的对象。如果您在内部使用一个iterable集合,这可以像返回该集合一样简单

在您的例子中,似乎希望对象的行为类似于元组的可编辑集合。您正在寻找的行为的一个可能实现是

class Example: 
    def __init__(self): 
        self.a=1 
        self.b=2 

    def __iter__(self): 
        for elem in ('a', 'b'): 
            yield (elem, getattr(self, elem))                                                                                                                

>>> dict(Example())                                                                                               
{'a': 1, 'b': 2}


在这里,我们使用a生成一个iterable,它将依次生成元组“a”、self.a和“b”、self.b。

您需要创建对象

list和tuple都接受iterable作为参数,它们将重复使用该参数,直到构造新集合为止。为了使您的类能够使用这种机制,您需要根据类的特定语义,至少定义方法,也可能定义方法

您的_iter___)实现将需要返回一个实现的对象。如果您在内部使用一个iterable集合,这可以像返回该集合一样简单

在您的例子中,似乎希望对象的行为类似于元组的可编辑集合。您正在寻找的行为的一个可能实现是

class Example: 
    def __init__(self): 
        self.a=1 
        self.b=2 

    def __iter__(self): 
        for elem in ('a', 'b'): 
            yield (elem, getattr(self, elem))                                                                                                                

>>> dict(Example())                                                                                               
{'a': 1, 'b': 2}


在这里,我们使用a来生成一个iterable,它将依次生成元组“a”、self.a和“b”、self.b。

大多数内置构造函数将iterable作为参数,因此您可以让您的类型iterable意识到一件重要的事情:存在一个ExampleClass。每个类都有一个ExampleClass属性,但不要覆盖它。它包含类的所有属性,除了通过键入instance将类转换为字典之外,还可以出于其他目的调用它。uuuu dict_uu…是的,uuuu dict_u是一个用于保存实例命名空间字典的属性。它不是dict构造函数的钩子,不像uuu int_uuuu注意,你的as_udict解决方案是完全合理的。@juanpa.arrivillaga:它确实有效,并且做了我想要的,但我喜欢能够在我的对象上应用“dict”或“list”的想法;在我看来,它使代码看起来更像python。我通常在通过类方法(例如Config.from_json或SomeObjectLoader.from_Config)定义构造函数时编写这些内容。。。。。但是,如果我想构建一个像dict或list这样的基本类型,我想最好是有一个python构造。大多数内置构造函数都以iterable作为参数,所以你可以让你的类型iterableI意识到一些重要的事情:有一个ExampleClass。每个类都有一个ExampleClass属性,但不要覆盖它。它包含类的所有属性,除了通过键入instance将类转换为字典之外,还可以出于其他目的调用它。uuuu dict_uu…是的,uuuu dict_u是一个用于保存实例命名空间字典的属性。它不是dict构造函数的钩子,与int不同,as_dict解决方案是完全真实的
sonable.@juanpa.arrivillaga:它确实有效,而且做了我想做的事情,但我喜欢能够在我的对象上应用“dict”或“list”的想法;在我看来,它使代码看起来更像python。我通常在通过类方法(例如Config.from_json或SomeObjectLoader.from_Config)定义构造函数时编写这些内容。。。。。但是如果我想构建一个像dict或list这样的基本类型,我想最好是有一个python结构。你几乎肯定不想定义uuu next uuu,因为这将使你的对象成为一个迭代器,而不仅仅是一个iterable@juanpa.arrivillaga没错,这取决于您定义的类的语义。您可以为iterable定义just uuuu iter uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我在回复中提到了这两个协议,作为教学点,以便OP了解这两个协议,允许他们选择更适合其应用的协议。@Brian:我已经了解迭代器和iterable协议,我只是不知道list和dict接受iterables,我认为它只接受迭代器,这意味着我必须调用dictterexample而不是dictExample。谢谢你的回答,很有启发性@帕特里克达席尔瓦不,那不是什么意思。即使他们只接受迭代器一个奇怪的需求,您也不必在将其传递给list或dict或任何其他容器构造函数之前调用itersome_迭代器,因为itersome_迭代器总是返回迭代器本身,也就是说,itersome_迭代器是迭代器,你几乎肯定不想定义下一个迭代器,因为这将使你的对象不仅仅是一个迭代器iterable@juanpa.arrivillaga没错,这取决于您定义的类的语义。您可以为iterable定义just uuuu iter uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。我在回复中提到了这两个协议,作为教学点,以便OP了解这两个协议,允许他们选择更适合其应用的协议。@Brian:我已经了解迭代器和iterable协议,我只是不知道list和dict接受iterables,我认为它只接受迭代器,这意味着我必须调用dictterexample而不是dictExample。谢谢你的回答,很有启发性@帕特里克达席尔瓦不,那不是什么意思。即使他们只接受迭代器一个奇怪的需求,您也不必在将其传递给list或dict或任何其他容器构造函数之前调用itersome_迭代器,因为itersome_迭代器总是返回迭代器本身,也就是说,itersome_迭代器是迭代器,适用于dict和list,因为它们是其他类型中的一种特殊类型,但是如果我想将其转换为int或float呢?我知道在这些情况下用例可能不是很清楚,老实说,我对你的答案很满意,但我只是想知道这是否可行。我已经能够使用迭代器和iterables,我只是认为这需要调用dicterexample而不是dictExample。那是个不错的主意@PatrickDaSilva为dict和list工作,因为它们是其他类型中的一种特殊类型。它们都是容器,但大多数内置类型都是容器。对于数字类型,有内置的钩子、\uuuuu int\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?我知道在这些情况下用例可能不是很清楚,老实说,我对你的答案很满意,但我只是想知道这是否可行。我已经能够使用迭代器和iterables,我只是认为这需要调用dicterexample而不是dictExample。那是个不错的主意@PatrickDaSilva为dict和list工作,因为它们是其他类型中的一种特殊类型。它们都是容器,但大多数内置类型都是容器。对于数值类型,有内置的钩子、int、float和complex。