jackjia 发表于 2020-6-15 18:04:33

关于初始化的问题,到底什么时候需要初始化?

下面的源代码中, class Line 为什么要写个初始化, 然后又导致 不得不再定义个函数来return?
写成我这样行不行?
class Line(Point):
    def getlen(self):
      self.L = p1.getX() - p2.getX()
      self.W = p1.getY() - p2.getY()
      return math.sqrt(self.x*self.x + self.y*self.y)


以下是源代码
import math

class Point():
    def __init__(self, x=0, y=0):
      self.x = x
      self.y = y

    def getX(self):
      return self.x

    def getY(self):
      return self.y

class Line():
    def __init__(self, p1, p2):
      self.x = p1.getX() - p2.getX()
      self.y = p1.getY() - p2.getY()
      self.len = math.sqrt(self.x*self.x + self.y*self.y)

    def getLen(self):
      return self.len

>>> p1 = Point(1, 1)
>>> p2 = Point(4, 5)
>>> line = Line(p1, p2)
>>> line.getLen()
5.0

heidern0612 发表于 2020-6-15 18:20:07

本帖最后由 heidern0612 于 2020-6-15 18:26 编辑

你line不初始化,你怎么往实例化里面传P1和P2的值?

就算你这么写没什么毛病,return 一大堆公式,不复杂吗?

python之禅其一就是简单比复杂好,清晰比困难好。

简单之道就是一眼望去就能大概知道返回的是个啥。

jackjia 发表于 2020-6-15 18:27:22

我这样写的, 也正常的运行功能了

import random as r

class Point():
   
    def __init__(self):
      self.x = r.randint(0,10)
      self.y = r.randint(0,10)
    def getX(self):
      return self.x
    def getY(self):
      return self.y

import math

class Line(Point):
    def getlen(self):
      self.L = p1.getX() - p2.getX()
      self.W = p1.getY() - p2.getY()
      return math.sqrt(self.x*self.x + self.y*self.y)

永恒的蓝色梦想 发表于 2020-6-15 18:50:39

jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r


不报 SyntaxError 肯定是能运行的{:10_277:}

heidern0612 发表于 2020-6-15 18:51:38

本帖最后由 heidern0612 于 2020-6-15 18:52 编辑

jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r


嗯,先不讨论对错的问题。

为啥非要把功能区和属性区规划到一类函数里面去呢?

照你这么算的话,那其实上面那个Point里面的__init__也不用写。

这么写小脚本是没什么,你写大程序的时候就会发现问题了,并不方便你后期维护和程序的扩展。

在你后期写代码多的时候,你能想的到宽和长这种静态变量被你定义到长度这个函数里了么?

Twilight6 发表于 2020-6-15 18:54:33

jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r




你这里实际上还是有初始化,因为你继承了 Point 类,所以 Point 类中的__init__方法也被你继承

但是为什么不初始化都可以得到答案,却要麻烦在初始化呢?

你可以试试吧你没初始化的实例对象使用 __dict__ 方法

你会发现,没初始化的会返回一个空字典,而初始化的会返回自己所有的实例属性

而且每个实例对象都是独有的实例属性,而不是共享的,对一些简单的编程,可能你感觉不到其作用的意义

但是对于比较大的项目,你就会发现这个作用的凸显吧

heidern0612 发表于 2020-6-15 19:02:27

本帖最后由 heidern0612 于 2020-6-15 19:31 编辑

jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r


再来讨论你__init__方法的问题。

你没发现,你有init的时候,实例的属性是绑定的,没有的时候,x和y并不是绑定给实例对象的。

这就会导致你每一个方法参数都需要有x和y,并且这个x和y是会随着你传入参数而变化的,这就算是实际修改的类属性,而不是实例属性。

而有了init,只需要在类中指定方法即可。

而且init最主要的功能就是自动为了传参,(否则实例化的字典参数为空,参见楼上回答)并且是为了下面调用方法做准备。

就好比你打个游戏,你不希望打怪的时候屏幕才给你显示血量吧?肯定是一开始游戏就有血量和蓝量这些静态参数显示给你。

init就大概类似这种一进游戏就自动调用的参数了。

jackjia 发表于 2020-6-15 20:59:57

heidern0612 发表于 2020-6-15 19:02
再来讨论你__init__方法的问题。

你没发现,你有init的时候,实例的属性是绑定的,没有的时候,x和y ...

我主要是不太懂init的底层逻辑和意义.
比如我看了你的回答, 产生了一个新的疑问: 这些静态参数如果直接写在类的下面, 和写在init函数下面,有什么区别呢?
比如:
class Line():
      self.x = p1.getX() - p2.getX()
      self.y = p1.getY() - p2.getY()
      self.len = math.sqrt(self.x*self.x + self.y*self.y)

    def getLen(self):
      return self.len

heidern0612 发表于 2020-6-16 08:12:08

jackjia 发表于 2020-6-15 20:59
我主要是不太懂init的底层逻辑和意义.
比如我看了你的回答, 产生了一个新的疑问: 这些静态参数如果直接 ...

你直接写类的函数里,跟你写在init里的区别就是:

前者只需要你实例化,这些属性自然就有了,可以直接调用。

后者还需要你类实例化后再调用类函数,才能使用这些属性。

你程序超过200行以上或者说你写个小工程,就知道这么写的好处了。

实在不行,不懂的就先放着,往后继续学,学着学着慢慢就明白了。
页: [1]
查看完整版本: 关于初始化的问题,到底什么时候需要初始化?