为什么我们在python类中使用__init__? [英] Why do we use __init__ in python classes?

查看:157
本文介绍了为什么我们在python类中使用__init__?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,如果这个问题有点笼统,但它一直在欺骗我,因为我不完全理解它。我是一个python新手,我所有的编程迄今为止已经是函数,我开始看看使用类(因为我将其他人的代码合并到我的程序)。



我理解类背后的想法(创建一个基本的功能,你可以修改不同的环境,像汽车类,你可以根据你的需要改变颜色) 。我无法理解类的初始化。他们的要点是什么,我们怎么知道要包括在他们什么?写在类中需要一个不同类型的思维,而不是创建函数(我想我可以只创建函数,然后将它们包装在一个类中,所以我可以重新使用它们,这将工作)?



下面是一个例子:

 类搜寻器:
#的数据库
def __init __(self,dbname):
self.con = sqlite.connect(dbname)

def __del __(self):
self.con。 close()

def dbcommit(self):
self.con.commit()

#then我理解的代码开始....



或另一个代码示例:

  class bicluster:
def __init __(self,vec,left = None,right = None,distance = 0.0,id = None):
self。 left = left
self.right = right
self.vec = vec
self.id = id
self.distance = distance

有很多这些我遇到(当试图阅读其他人的代码),但我有点失去理解的逻辑创建他们。对不起,如果这个问题是超级基本的,我搜索,因为我觉得我应该知道这一点,但我很困惑。

解决方案

根据你写的内容,你缺少一个重要的理解:类和对象之间的差异。 __ init __ 不初始化类,它初始化类或对象的实例。每只狗都有颜色,但狗作为一个类不。每只狗有四个或更少的脚,但狗的类不。类是对象的概念。当你看到Fido和Spot,你会认出他们的相似性,他们的狗。



当你说

  class Dog:
def __init __(self,legs,color):
self.legs = legs
self.colour = color

fido = Dog(4,brown)
spot = Dog(3,mostly yellow)

一只有4条腿的棕色狗,而斑点有点跛子,大多是黄色的。 __ init __ 函数称为构造函数或初始化程序,并且在创建类的新实例时自动调用。在该函数中,新创建的对象被分配给参数 self 。符号 self.legs 是变量中的对象的 legs / code>。属性类似变量,但它们描述对象的状态,或对象可用的特定动作(函数)。



但是,请注意, set color 是一个抽象的概念。有些属性在类上有意义。例如, population_size 是一个这样 - 对Fido计数没有意义,因为Fido总是一个。计数狗是有意义的。让我们说世界上有2亿只狗。这是Dog类的属性。 Fido与2亿无关,Spot也没有。它被称为类属性,而不是上面 color legs 的实例属性 p>

现在,更少的东西和更多的编程相关。正如我在下面写的,类添加东西是不明智的 - 它是什么类? Python中的类构成了不同数据的集合,它们的行为类似。狗类包括Fido和Spot和199999999998其他类似的动物,他们都在路灯柱上撒尿。添加事物的类是什么?通过什么数据固有的他们不同?他们分享什么行动?



但是,数字...那些是更有趣的话题。说,整数。有很多他们,比狗多得多。我知道Python已经有整数,但让我们玩蠢,并再次实现(通过欺骗和使用Python的整数)。



所以,整数是一个类。他们有一些数据(值)和一些行为(添加到这个其他数字)。让我们看看这个:

  class MyInteger:
def __init __(self,newvalue)
#索引卡。
#在value的标题下,我们将写入
#变量newvalue的内容。
self.value = newvalue
def add(self,other):
#当一个整数想要将自己添加到另一个整数时,
#我们将取其值并添加他们在一起,
#然后使用一个新的整数与结果值。
return MyInteger(self.value + other.value)

three = MyInteger(3)
#3现在包含一个MyInteger类的对象
#three.value现在是3
five = MyInteger(5)
#5现在包含类MyInteger的对象
#five.value现在是5
eight = three.add(五)
#这里,我们调用三个行为添加另一个整数
#now,eight.value是three.value + five.value = 3 + 5 = 8
print eight.value
#==> 8

这有点脆弱(我们假设其他将是一个MyInteger),但我们现在将忽略。在实际代码中,我们不会;我们会测试它,以确保,甚至强制它(你不是一个整数,golly,你有10纳秒成为一个!9 ... 8 ....)



我们甚至可以定义分数。分数也知道如何添加自己。

  class MyFraction:
def __init __(self,newnumerator,newdenominator)
self.numerator = newnumerator
self.denominator = newdenominator
#因为每个部分都是由这两个东西描述的
def add(self,other):
newdenominator = self。 denominator * other.denominator
newnumerator = self.numerator * other.denominator + self.denominator * other.numerator
return MyFraction(newnumerator,newdenominator)

比整数更多的分数(不是真的,但计算机不知道)。让我们做两个:

  half = MyFraction(1,2)
third = MyFraction $ b five_sixths = half.add(third)
print five_sixths.numerator
#==> 5
print five_sixths.denominator
#==> 6

你实际上没有声明任何东西。属性就像一种新的变量。正常变量只有一个值。让我们说你写 color =grey。您不能有另一个名为 color 的变量,即fuchsia - 不在代码中的相同位置。



数组解决到某种程度。如果你说 color = [grey,fuchsia] ,你将两种颜色堆叠在变量中,但你可以用它们的位置(0或1,在这种情况下)。



属性是绑定到对象的变量。与数组一样,我们可以在不同的狗上拥有大量的颜色变量。因此, fido.colour 是一个变量,但 spot.colour 是另一个变量。第一个绑定到变量 fido 中的对象;第二个, spot 。现在,当你调用 Dog(4,brown) three.add(five)始终是一个不可见的参数,它将被分配给参数列表前面悬空的额外参数。它通常被称为 self ,并且将获取点前面的对象的值。因此,在Dog的 __ init __ (构造函数)中, self 将是新的Dog会是什么; 内的 变量三中的对象。因此, three.value 将是 add 之外的同一个变量,因为 self.value $



如果我说 the_mangy_one = fido ,我将使用另一个名称开始引用名为 fido 的对象。从现在起, fido.colour the_mangy_one.colour 完全相同的变量。



所以, __ init __ 里面的东西。你可以认为他们是注意到狗的出生证明。 color 本身是一个随机变量,可以包含任何内容。 fido.colour self.colour 就像Dog的身份证上的表单域; __ init __ 是第一次填写的职员。



任何更清楚?



EDIT :展开以下注释:



strong>,不是吗?



首先, fido 实际上不是一个对象。它是一个变量,它当前包含一个对象,就像当你说 x = 5 x 变量当前包含数字5。如果你以后改变主意,你可以做 fido = Cat(4,pleasing)(只要你创建了一个类 Cat )和 fido 将从包含一个cat对象。如果你 fido = x ,它将包含数字5,而不是动物对象。



类本身不知道它的实例,除非你专门编写代码来跟踪它们。例如:

  class Cat:
census = []

def __init ,leg,color):
self.colour = color
self.legs = legs
Cat.census.append(self)

这里, census Cat class。

  fluffy = Cat(4,white)
spark = Cat )
Cat.census
#==> [< __ main__.Cat instance at 0x108982cb0>,< __ main__.Cat instance at 0x108982e18>]
#或类似的东西

注意,你不会得到 [fluffy,sparky] 。这些只是变量名。如果你想要猫自己有名字,你必须为该名称单独的属性,然后重写 __ str __ 方法返回这个名字。这个方法(即类绑定函数,就像 add __ init __ )目的是描述如何转换对象到一个字符串,就像当你打印出来。


Sorry if this question is a bit general but its been bugging me because I don't fully understand it. I'm a python newbie and all my programming so far has been functions and I'm starting to look at using classes(since I'm incorporating some other people's code into my programs).

I understand the idea behind classes(creates basically a function that you can modify for different environments..like a car class that you can change the color depending on your needs). I'm having trouble understanding the Initialization of the classes. What's the point of them and how do we know what to include in them? Does writing in classes require a different type of thinking versus creating functions(I figured I could just create functions and then just wrap them in a class so I can re-use them..will that work)?

Here's an example:

class crawler:
  # Initialize the crawler with the name of database
  def __init__(self,dbname):
    self.con=sqlite.connect(dbname)

  def __del__(self):
    self.con.close()

  def dbcommit(self):
    self.con.commit()

#then the code that I understand starts....

Or another code sample:

class bicluster:
  def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
    self.left=left
    self.right=right
    self.vec=vec
    self.id=id
    self.distance=distance

There is so many of these I come across(when trying to read other people's code) but I'm somewhat at a loss to understand the logic in creating them. I'm sorry if this question is super basic, I searched around because I feel I should know this but I'm pretty confused. Any clarification on how this works would be great.

解决方案

By what you wrote, you are missing a critical piece of understanding: the difference between a class and an object. __init__ doesn't initialize a class, it initializes an instance of a class or an object. Each dog has colour, but dogs as a class don't. Each dog has four or fewer feet, but the class of dogs doesn't. The class is a concept of an object. When you see Fido and Spot, you recognise their similarity, their doghood. That's the class.

When you say

class Dog:
    def __init__(self, legs, colour):
        self.legs = legs
        self.colour = colour

fido = Dog(4, "brown")
spot = Dog(3, "mostly yellow")

You're saying, Fido is a brown dog with 4 legs while Spot is a bit of a cripple and is mostly yellow. The __init__ function is called a constructor, or initializer, and is automatically called when you create a new instance of a class. Within that function, the newly created object is assigned to the parameter self. The notation self.legs is an attribute called legs of the object in the variable self. Attributes are kind of like variables, but they describe the state of an object, or particular actions (functions) available to the object.

However, notice that you don't set colour for the doghood itself - it's an abstract concept. There are attributes that make sense on classes. For instance, population_size is one such - it doesn't make sense to count the Fido because Fido is always one. It does make sense to count dogs. Let us say there're 200 million dogs in the world. It's the property of the Dog class. Fido has nothing to do with the number 200 million, nor does Spot. It's called a "class attribute", as opposed to "instance attributes" that are colour or legs above.

Now, to something less canine and more programming-related. As I write below, class to add things is not sensible - what is it a class of? Classes in Python make up of collections of different data, that behave similarly. Class of dogs consists of Fido and Spot and 199999999998 other animals similar to them, all of them peeing on lampposts. What does the class for adding things consist of? By what data inherent to them do they differ? And what actions do they share?

However, numbers... those are more interesting subjects. Say, Integers. There's a lot of them, a lot more than dogs. I know that Python already has integers, but let's play dumb and "implement" them again (by cheating and using Python's integers).

So, Integers are a class. They have some data (value), and some behaviours ("add me to this other number"). Let's show this:

class MyInteger:
    def __init__(self, newvalue)
        # imagine self as an index card.
        # under the heading of "value", we will write
        # the contents of the variable newvalue.
        self.value = newvalue
    def add(self, other):
        # when an integer wants to add itself to another integer,
        # we'll take their values and add them together,
        # then make a new integer with the result value.
        return MyInteger(self.value + other.value)

three = MyInteger(3)
# three now contains an object of class MyInteger
# three.value is now 3
five = MyInteger(5)
# five now contains an object of class MyInteger
# five.value is now 5
eight = three.add(five)
# here, we invoked the three's behaviour of adding another integer
# now, eight.value is three.value + five.value = 3 + 5 = 8
print eight.value
# ==> 8

This is a bit fragile (we're assuming other will be a MyInteger), but we'll ignore now. In real code, we wouldn't; we'd test it to make sure, and maybe even coerce it ("you're not an integer? by golly, you have 10 nanoseconds to become one! 9... 8....")

We could even define fractions. Fractions also know how to add themselves.

class MyFraction:
    def __init__(self, newnumerator, newdenominator)
        self.numerator = newnumerator
        self.denominator = newdenominator
        # because every fraction is described by these two things
    def add(self, other):
        newdenominator = self.denominator * other.denominator
        newnumerator = self.numerator * other.denominator + self.denominator * other.numerator
        return MyFraction(newnumerator, newdenominator)

There's even more fractions than integers (not really, but computers don't know that). Let's make two:

half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6

You're not actually declaring anything here. Attributes are like a new kind of variable. Normal variables only have one value. Let us say you write colour = "grey". You can't have another variable named colour that is "fuchsia" - not in the same place in the code.

Arrays solve that to a degree. If you say colour = ["grey", "fuchsia"], you have stacked two colours into the variable, but you distinguish them by their position (0, or 1, in this case).

Attributes are variables that are bound to an object. Like with arrays, we can have plenty colour variables, on different dogs. So, fido.colour is one variable, but spot.colour is another. The first one is bound to the object within the variable fido; the second, spot. Now, when you call Dog(4, "brown"), or three.add(five), there will always be an invisible parameter, which will be assigned to the dangling extra one at the front of the parameter list. It is conventionally called self, and will get the value of the object in front of the dot. Thus, within the Dog's __init__ (constructor), self will be whatever the new Dog will turn out to be; within MyInteger's add, self will be bound to the object in the variable three. Thus, three.value will be the same variable outside the add, as self.value within the add.

If I say the_mangy_one = fido, I will start referring to the object known as fido with yet another name. From now on, fido.colour is exactly the same variable as the_mangy_one.colour.

So, the things inside the __init__. You can think of them as noting things into the Dog's birth certificate. colour by itself is a random variable, could contain anything. fido.colour or self.colour is like a form field on the Dog's identity sheet; and __init__ is the clerk filling it out for the first time.

Any clearer?

EDIT: Expanding on the comment below:

You mean a list of objects, don't you?

First of all, fido is actually not an object. It is a variable, which is currently containing an object, just like when you say x = 5, x is a variable currently containing the number five. If you later change your mind, you can do fido = Cat(4, "pleasing") (as long as you've created a class Cat), and fido would from then on "contain" a cat object. If you do fido = x, it will then contain the number five, and not an animal object at all.

A class by itself doesn't know its instances unless you specifically write code to keep track of them. For instance:

class Cat:
    census = []

    def __init(self, legs, colour):
        self.colour = colour
        self.legs = legs
        Cat.census.append(self)

Here, census is a class-level attribute of Cat class.

fluffy = Cat(4, "white")
spark = Cat(4, "fiery")
Cat.census
# ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>]
# or something like that

Note that you won't get [fluffy, sparky]. Those are just variable names. If you want cats themselves to have names, you have to make a separate attribute for the name, and then override the __str__ method to return this name. This method's (i.e. class-bound function, just like add or __init__) purpose is to describe how to convert the object to a string, like when you print it out.

这篇关于为什么我们在python类中使用__init__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆