简体   繁体   English

Python 类返回值

[英]Python class returning value

I'm trying to create a class that returns a value, not self.我正在尝试创建一个返回值而不是自我的类。

I will show you an example comparing with a list:我将向您展示一个与列表进行比较的示例:

>>> l = list()
>>> print(l)
[]
>>> class MyClass:
>>>     pass

>>> mc = MyClass()
>>> print mc
<__main__.MyClass instance at 0x02892508>

I need that MyClass returns a list, like list() does, not the instance info.我需要 MyClass 返回一个列表,就像list()一样,而不是实例信息。 I know that I can make a subclass of list.我知道我可以创建列表的子类。 But is there a way to do it without subclassing?但是有没有办法在没有子类化的情况下做到这一点?

I want to imitate a list (or other objects):我想模仿一个列表(或其他对象):

>>> l1 = list()
>>> l2 = list()
>>> l1
[]
>>> l2
[]
>>> l1 == l2
True
>>> class MyClass():
def __repr__(self):
    return '[]'


>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1
[]
>>> m2
[]
>>> m1 == m2
False

Why is m1 == m2 False?为什么m1 == m2假的? This is the question.这是问题。

I'm sorry if I don't respond to all of you.如果我没有回复大家,我很抱歉。 I'm trying all the solutions you give me.我正在尝试您给我的所有解决方案。 I cant use def , because I need to use functions like setitem, getitem, etc.我不能使用def ,因为我需要使用 setitem、getitem 等函数。

I think you are very confused about what is occurring.我认为您对正在发生的事情感到非常困惑。

In Python, everything is an object:在 Python 中,一切都是对象:

  • [] (a list) is an object [] (一个列表)是一个对象
  • 'abcde' (a string) is an object 'abcde' (字符串)是一个对象
  • 1 (an integer) is an object 1 (整数)是一个对象
  • MyClass() (an instance) is an object MyClass() (一个实例)是一个对象
  • MyClass (a class) is also an object MyClass (一个类)也是一个对象
  • list (a type--much like a class) is also an object list (一种类型——很像一个类)也是一个对象

They are all "values" in the sense that they are a thing and not a name which refers to a thing.从它们是事物而不是指代事物的名称的意义上说,它们都是“值”。 (Variables are names which refer to values.) A value is not something different from an object in Python. (变量是引用值的名称。)值与 Python 中的对象没有什么不同。

When you call a class object (like MyClass() or list() ), it returns an instance of that class.当您调用类对象(如MyClass()list() )时,它会返回该类的实例。 ( list is really a type and not a class, but I am simplifying a bit here.) list实际上是一种类型而不是类,但我在这里稍微简化了一些。)

When you print an object (ie get a string representation of an object), that object's __str__ or __repr__ magic method is called and the returned value printed.当您打印一个对象(即获取一个对象的字符串表示)时,将调用该对象的__str____repr__魔术方法并打印返回值。

For example:例如:

>>> class MyClass(object):
...     def __str__(self):
...             return "MyClass([])"
...     def __repr__(self):
...             return "I am an instance of MyClass at address "+hex(id(self))
... 
>>> m = MyClass()
>>> print m
MyClass([])
>>> m
I am an instance of MyClass at address 0x108ed5a10
>>> 

So what you are asking for, "I need that MyClass return a list, like list(), not the instance info," does not make any sense.所以你所要求的,“我需要 MyClass 返回一个列表,比如 list(),而不是实例信息”,没有任何意义。 list() returns a list instance. list()返回一个列表实例。 MyClass() returns a MyClass instance. MyClass()返回一个 MyClass 实例。 If you want a list instance, just get a list instance.如果你想要一个列表实例,只需获取一个列表实例。 If the issue instead is what do these objects look like when you print them or look at them in the console , then create a __str__ and __repr__ method which represents them as you want them to be represented.如果问题是当您print这些对象或在控制台中查看它们时,这些对象什么样子的,那么创建一个__str____repr__方法,以按照您希望的方式表示它们。

Update for new question about equality关于平等的新问题的更新

Once again, __str__ and __repr__ are only for printing , and do not affect the object in any other way.再次声明, __str____repr__仅用于打印,不会以任何其他方式影响对象。 Just because two objects have the same __repr__ value does not mean they are equal!仅仅因为两个对象具有相同的__repr__值并不意味着它们相等!

MyClass() != MyClass() because your class does not define how these would be equal, so it falls back to the default behavior (of the object type), which is that objects are only equal to themselves: MyClass() != MyClass()因为你的类没有定义它们如何相等,所以它回退到默认行为( object类型),即对象只等于它们自己:

>>> m = MyClass()
>>> m1 = m
>>> m2 = m
>>> m1 == m2
True
>>> m3 = MyClass()
>>> m1 == m3
False

If you want to change this, use one of the comparison magic methods如果要更改此设置,请使用比较魔术方法之一

For example, you can have an object that is equal to everything:例如,您可以拥有一个等于一切的对象:

>>> class MyClass(object):
...     def __eq__(self, other):
...             return True
... 
>>> m1 = MyClass()
>>> m2 = MyClass()
>>> m1 == m2
True
>>> m1 == m1
True
>>> m1 == 1
True
>>> m1 == None
True
>>> m1 == []
True

I think you should do two things:我认为你应该做两件事:

  1. Take a look at this guide to magic method use in Python .看看这个在 Python 中使用魔法方法的指南
  2. Justify why you are not subclassing list if what you want is very list-like.如果您想要的非常类似于list ,请证明为什么不将list子类化。 If subclassing is not appropriate, you can delegate to a wrapped list instance instead:如果子类化不合适,您可以委托给一个包装的列表实例:

     class MyClass(object): def __init__(self): self._list = [] def __getattr__(self, name): return getattr(self._list, name) # __repr__ and __str__ methods are automatically created # for every class, so if we want to delegate these we must # do so explicitly def __repr__(self): return "MyClass(%s)" % repr(self._list) def __str__(self): return "MyClass(%s)" % str(self._list)

    This will now act like a list without being a list (ie, without subclassing list ).这现在将像一个列表而不是一个列表(即,没有子类化list )。

     >>> c = MyClass() >>> c.append(1) >>> c MyClass([1])

If what you want is a way to turn your class into kind of a list without subclassing list , then just make a method that returns a list:如果你想要的是一种将你的类变成一种列表而不需要子类化list的方法,那么只需创建一个返回列表的方法:

def MyClass():
    def __init__(self):
        self.value1 = 1
        self.value2 = 2

    def get_list(self):
        return [self.value1, self.value2...]


>>>print MyClass().get_list()
[1, 2...]

If you meant that print MyClass() will print a list, just override __repr__ :如果您的意思是print MyClass()将打印一个列表,只需覆盖__repr__

class MyClass():        
    def __init__(self):
        self.value1 = 1
        self.value2 = 2

    def __repr__(self):
        return repr([self.value1, self.value2])

EDIT: I see you meant how to make objects compare .编辑:我明白你的意思是如何让对象进行比较 For that, you override the __cmp__ method.为此,您覆盖了__cmp__方法。

class MyClass():
    def __cmp__(self, other):
        return cmp(self.get_list(), other.get_list())

Use __new__ to return value from a class.使用__new__从类返回值。

As others suggest __repr__ , __str__ or even __init__ (somehow) CAN give you what you want, But __new__ will be a semantically better solution for your purpose since you want the actual object to be returned and not just the string representation of it.正如其他人所建议的__repr____str__甚至__init__ (以某种方式)可以给你你想要的东西,但是__new__将是一个语义上更好的解决方案,因为你想要返回实际的对象,而不仅仅是它的字符串表示。

Read this answer for more insights into __str__ and __repr__ https://stackoverflow.com/a/19331543/4985585阅读此答案以获取有关__str____repr__更多见解https://stackoverflow.com/a/19331543/4985585

class MyClass():
    def __new__(cls):
        return list() #or anything you want

>>> MyClass()
[]   #Returns a true list not a repr or string
class MyClass():
    def __init__(self, a, b):
        self.value1 = a
        self.value2 = b

    def __call__(self):
        return [self.value1, self.value2]

Testing:测试:

>>> x = MyClass('foo','bar')
>>> x()
['foo', 'bar']

You are describing a function, not a class.您正在描述一个函数,而不是一个类。

def Myclass():
    return []

the worked proposition for me is __call__ on class who create list of little numbers:对我来说__call__提议是__call__在创建小数字列表的课堂上:

import itertools
    
class SmallNumbers:
    def __init__(self, how_much):
        self.how_much = int(how_much)
        self.work_list = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉']
        self.generated_list = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉']
        start = 10
        end = 100
        for cmb in range(2, len(str(self.how_much)) + 1):
            self.ListOfCombinations(is_upper_then=start, is_under_then=end, combinations=cmb)
            start *= 10
            end *= 10

    def __call__(self, number, *args, **kwargs):
        return self.generated_list[number]

    def ListOfCombinations(self, is_upper_then, is_under_then, combinations):
        multi_work_list = eval(str('self.work_list,') * combinations)
        nbr = 0
        for subset in itertools.product(*multi_work_list):
            if is_upper_then <= nbr < is_under_then:
                self.generated_list.append(''.join(subset))
                if self.how_much == nbr:
                    break
            nbr += 1

and to run it:并运行它:

if __name__ == '__main__':
        sm = SmallNumbers(56)
        print(sm.generated_list)
        print(sm.generated_list[34], sm.generated_list[27], sm.generated_list[10])
        print('The Best', sm(15), sm(55), sm(49), sm(0))

result结果

['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉', '₁₀', '₁₁', '₁₂', '₁₃', '₁₄', '₁₅', '₁₆', '₁₇', '₁₈', '₁₉', '₂₀', '₂₁', '₂₂', '₂₃', '₂₄', '₂₅', '₂₆', '₂₇', '₂₈', '₂₉', '₃₀', '₃₁', '₃₂', '₃₃', '₃₄', '₃₅', '₃₆', '₃₇', '₃₈', '₃₉', '₄₀', '₄₁', '₄₂', '₄₃', '₄₄', '₄₅', '₄₆', '₄₇', '₄₈', '₄₉', '₅₀', '₅₁', '₅₂', '₅₃', '₅₄', '₅₅', '₅₆']
₃₄ ₂₇ ₁₀
The Best ₁₅ ₅₅ ₄₉ ₀

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM