创建类时何时使用__init__方法?

3
在使用 Django 一段时间后,我习惯于在声明变量时不使用 def __init__(self): ... 这个类。过去我会在 __init__ 函数中声明我的变量,现在我意识到并非所有情况都需要这样做,但我不清楚何时使用它或不使用它。当尝试将一个类传递给一个变量时似乎会出现问题,在这些情况下应该使用 init 吗?
我知道我可以在所有情况下都使用 __init__,但如果没有它,我的短类看起来更整洁,因此我想知道何时可以使用它以及何时不可以使用它。
例如:
class BaseScraper(object):
    # whithout __init__, passing Site() to site wont work.
    # site = Site()
    # parser = None

    def __init__(self):
        self.site = Site()
        self.parser = None 


class Site(object):
    # no trouble declaring url as a str
    url = ""

    def set(self, url):
        self.url = url

    def get(self):
        return self.url



if __name__ == "__main__":
    scraper = BaseScraper()

    scraper.site.set('http://www.google.com')   
    print scraper.site.get()

1
Django 并不完全代表 Python。Django 模型字段是类级属性,实际上它们是实际对象,不是完全“持有”您的数据,并且它们作为元数据,Model__init__() 方法(或该代码块的其他部分)可自动创建实例级属性并执行一堆其他操作。Python 通常并不是这样工作的。 - millimoose
1
当初始化实例数据时,除非你知道自己在做什么,否则应该在 __init__ 中这样做。(类级别的属性有点像实例属性的默认值,但有很多限制条件。) - millimoose
这很有趣,谢谢你的解释。 - Brandon Nadeau
2个回答

6
类中声明的属性是属于类而不是个别类实例的。在您的site示例中,url不再是单个Site对象的属性,就像setget一样。对于这种类型的示例,您需要实例数据-您可以在__init__中初始化它们。 Python:类属性和实例属性之间的区别有一个很好的讨论。

1
这个失败是因为 Site 类还没有被定义。 并且(如 @Peter DeGlopper 所说),类变量和实例变量之间有很大的区别。
class BaseScraper(object):
    # This fails!
    site = Site()
    parser = None


class Site(object):
    # no trouble declaring url as a str
    url = ""

    def set(self, url):
        self.url = url

    def get(self):
        return self.url

当虚拟机编译Python模块时,会读取并编译类声明中的所有内容,但在方法声明(例如def __init__(...):)中,只会读取此行代码,忽略方法体。
例子:
class Foo(object):
    bar1 = "bar"
    foo1 = "foo"

    def __init__(self):
        self.bar2 = "BAZ"

foo = Foo #Put a class in a veriable? yes, you can.
foo.bar1 # returns "bar"
foo.foo1 # returns "foo"
foo.bar2 # fails!!!! This will be a instance variable, but doesn't exist yet

foo2 = Foo() # Here the __init__ is called
foo2.bar2 # returns "BAZ"
foo2.bar1 #Returns "bar" because all class variables are availables from instances

希望这可以帮助 =)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接