如何在Python中从__init__返回值?


102

我有一个带__init__功能的课。

创建对象时如何从该函数返回整数值?

我写了一个程序,在其中进行__init__命令行解析,我需要设置一些值。可以在全局变量中设置它并在其他成员函数中使用它吗?如果是这样,该怎么做?到目前为止,我在课外声明了一个变量。并将其设置为一个功能不会反映在其他功能中?


8
如果您正在考虑返回错误代码,请引发异常。
JoeG

1
请删除您的评论并更新您的问题。您拥有这个问题。这是你的问题。请修正问题以正确显示您的真正问题是什么。你在滥用__init__; 如果您描述您真正要完成的工作,我们可以为您提供帮助。
S.Lott

Answers:


117

__init__必须返回无。您不能(或至少不应该)返回其他东西。

尝试做任何您想返回的实例变量(或函数)。

>>> class Foo:
...     def __init__(self):
...         return 42
... 
>>> foo = Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() should return None

24
+1:您无法退回其他东西。这没有任何意义。
S.Lott

72
init不会返回新创建的对象-如TypeError所示,它需要返回None,对吗?新创建的对象由new返回,init只是设置其一些属性。但是,是的,正如您所说,将initnew更改为返回其他内容确实没有任何意义。
weronika 2011年

这是new哪里 new在Python中是隐式的吗?我认为Python的语义不同于Java和其他使用此词的语言。
2013年

1
@shiva AFAIK,由新的weronika表示__new __(self)不是一般的Java语义。
严厉的达夫塔里

2
仅仅因为不能完成并不意味着它没有意义。例如,最好将数据从传递super().__init__给派生类,而不必通过实例变量进行中继。
cz

123

你为什么想这么做?

如果要在调用类时返回其他对象,请使用以下__new__()方法:

class MyClass(object):
    def __init__(self):
        print "never called in this case"
    def __new__(cls):
        return 42

obj = MyClass()
print obj

9
是的,new是在使用类时返回除类实例以外的东西的正确方法……我只是想知道-您实际上是否有任何理由要这样做呢?
weronika 2011年

33
@weronika一个想法:在通常使用工厂的任何情况下,您都有一些理由要呈现一个类似于普通类实例化的接口。示例:在类中添加一些新的可选参数时__init__,您意识到,实际上,为了提供所需的灵活性,您需要一个类工厂,该工厂返回专用子类的实例。但是您图书馆的用户已经在使用您现有的API。为了保留它,您可以重写__new__以返回您的专用子类的实例。
Mark Amery 2014年

10
如果要查看Mark Amery所说的示例,请datetime从标准库中查看该模块的源代码。它以__new__这种方式使用。
泽林2015年

另外,如果有人想这样做,请确保从对象继承,否则它将无法正常工作。
Mino_e

我有点想到这个笨蛋,仅使用常规函数会更有意义。对于Java方面的人来说可能有点陌生(函数不在类中吗?异端!),但是它是pythonic。(您也可以在funtionName.val = ..中为函数分配属性,虽然有点荒谬,但是可以使用)
Shayne

37

从以下文档中__init__

作为对构造函数的特殊限制,不能返回任何值。这样做将导致在运行时引发TypeError。

作为证明,此代码:

class Foo(object):
    def __init__(self):
        return 2

f = Foo()

给出此错误:

Traceback (most recent call last):
  File "test_init.py", line 5, in <module>
    f = Foo()
TypeError: __init__() should return None, not 'int'

17

有问题的示例用法如下:

class SampleObject(object):

    def __new__(cls, item):
        if cls.IsValid(item):
            return super(SampleObject, cls).__new__(cls)
        else:
            return None

    def __init__(self, item):
        self.InitData(item) #large amount of data and very complex calculations

...

ValidObjects = []
for i in data:
    item = SampleObject(i)
    if item:             # in case the i data is valid for the sample object
        ValidObjects.append(item)

我没有足够的声誉,所以我无法发表评论,这太疯狂了!我希望我可以将其发布为对weronika的评论


3
这将引发NameError:self未在__new__(cls, Item)
Hart Simha

15

__init__与其他方法和函数一样,该方法默认情况下在没有return语句的情况下返回None,因此您可以像以下任何一种一样编写它:

class Foo:
    def __init__(self):
        self.value=42

class Bar:
    def __init__(self):
        self.value=42
        return None

但是,当然,添加return None并不会给您带来任何好处。

我不确定您要追求的是什么,但是您可能会对其中之一感兴趣:

class Foo:
    def __init__(self):
        self.value=42
    def __str__(self):
        return str(self.value)

f=Foo()
print f.value
print f

印刷品:

42
42

哦..我可以从类中访问成员变量吗?那应该可以解决我的问题....谢谢
webminal.org 2010年

@lakshmipathi,是的,像这样的实例变量是公共的。
quamrana 2010年

作为上课后返回有价值的东西的唯一途径:f = Foo().value
JLT

@JLT是的,您可以始终这样做,但这仍然并不意味着会返回任何内容__init__
quamrana '16


4

您可以将其设置为类变量,然后从主程序中读取它:

class Foo:
    def __init__(self):
        #Do your stuff here
        self.returncode = 42
bar = Foo()
baz = bar.returncode

2

只需添加即可,您可以在 __init__

@property
def failureException(self):
    class MyCustomException(AssertionError):
        def __init__(self_, *args, **kwargs):
            *** Your code here ***
            return super().__init__(*args, **kwargs)

    MyCustomException.__name__ = AssertionError.__name__
    return MyCustomException

上面的方法可以帮助您对测试中的异常执行特定的操作


2
super().__init__是returning None,所以您要返回None,这很好,但是很多余。
cz

2

init()返回无值,完美解决

class Solve:
def __init__(self,w,d):
    self.value=w
    self.unit=d
def __str__(self):
    return str("my speed is "+str(self.value)+" "+str(self.unit))
ob=Solve(21,'kmh')
print (ob)

输出:我的速度是21 kmh


-2

好吧,如果您不再关心对象实例,则可以替换它!

class MuaHaHa():
def __init__(self, ret):
    self=ret

print MuaHaHa('foo')=='foo'

2
那只是改变了分配给该self构造函数内部名称的内容。
Ondrej K.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.