例1: 使用__init__求和
class Person():
def __init__(self, x, y):
self.x = x
self.y = y
# return self.x + self.y # __init__函数没有返回值
def math(self):
return self.x+self.y
P1 = Person(5, 6)
print(P1.math())
例2: 不使用__init__
class Person():
def math(self, x, y):
return x+y
P1 = Person()
print(P1.math(5, 6))
在知乎上找了几个回答, 其中一个高赞的回答逻辑很奇怪, 他创建一个空的class, 然后说需要在类的外部对数据进行计算, 这种方式有很多缺点. 如下例子. 无法理解这是想表达什么.......
class Person():
pass
P1 = Person()
P1.x=5
P1.y=6
math=P1.x+P1.y
print(math)
例1和例2有什么区别吗? 没有体会到__init__
的优点啊? 或者是我举的例子不好? __init__
在实际开发中有什么作用呢? 多谢了.
给个知乎的连接吧,知乎的例子说的应该是:
两个人合作,每人完成一个任务。前者的完成任务2的人,不需要知道
Person
的内部属性,但是后者需要两人事先约定Person
的内部属性。所有代码相关代码写到一块,由一个人维护,要比两个人共同维护好。对于第二种写法,如果有一天完成任务1的人把math
改成了def math(self): self._z + self._y
,如果他没有通知完成任务2的人,那么整个程序将会挂掉。而如果写到了一起,那么由一个人维护,他就会把两处都改了,另一个人不需要做任何额外的修改。所以如果要写成后者,我们更愿意写成,完成任务1的人生成一个会计算加法的Person
,而完成任务2的人使用Person
计算了5+6
:所以,你给的两种写法都可以,只是他们留了不同的接口。至于那种更好么,应用场景决定(如何选择就是能不能写出优秀代码的难点)。
除了编译器提供的内置类型,我们还可以自定义类型。为了构造自己的类型,我们需要自己给出自定义类型的定义以及如何创建和初始化这个类型。“构造函数”就给出了如何创建以及初始化这个类型。
Python
是弱类型,所有对象构造方法一样,只是初始化不一样,所以这个函数叫做init
。这个__init__
就是一个“构造函数”!这个函数在创建对象的时候由编译器自动调用,并且编译器会忽略他的返回值。其实真正的构造函数是__new__
,由__new__
创建对象,然后把这个对象当做self
传递给__init__
,所以__init__
不需要返回值。从另一个角度来说,构造函数的作用是:类型转换, 类型转换, 类型转换。第一个
Person
可以把tuple
类(x,y)
转换成了一个只会计算x+y
的Person
。而第二种写法把()
转换成了一个会计算加法的Person
--因为遵循了迪米特法则,一句话搞定而不是解释半天。在其他一些语言里,构造函数是与类名相同的一个函数。这些语言里更容易理解
P1 = Person(5,6)
里的Person
更多的是一个函数,而不是一个类名。只是这个函数名与类名重名而已。Python里的__init__
就是构造函数完成初始化对象的那一部分,它的参数就是所有构造函数的参数+已经构造出的对象。