鱼C论坛

 找回密码
 立即注册
查看: 1025|回复: 8

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

[复制链接]
发表于 2020-6-15 18:04:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
下面的源代码中, 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-15 18:20:07 | 显示全部楼层
本帖最后由 heidern0612 于 2020-6-15 18:26 编辑

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

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

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

简单之道就是一眼望去就能大概知道返回的是个啥。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-15 18:50:39 | 显示全部楼层
jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r

不报 SyntaxError 肯定是能运行的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-15 18:51:38 | 显示全部楼层
本帖最后由 heidern0612 于 2020-6-15 18:52 编辑
jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r


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

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

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

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

在你后期写代码多的时候,你能想的到宽和长这种静态变量被你定义到长度这个函数里了么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-15 18:54:33 | 显示全部楼层
jackjia 发表于 2020-6-15 18:27
我这样写的, 也正常的运行功能了

import random as r



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

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

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

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

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

但是对于比较大的项目,你就会发现这个作用的凸显吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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就大概类似这种一进游戏就自动调用的参数了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

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

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

实在不行,不懂的就先放着,往后继续学,学着学着慢慢就明白了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-20 16:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表