金融网站知识图谱问答系统:自学Python第二周

def函数

语法

def function_name():
    expressions

Python 使用def 开始函数定义,紧接着是函数名,括号内部为函数的参数,内部为函数的具体功能实现代码,如果想要函数有返回值, 在 expressions 中的逻辑代码中用return 返回。

实例

def function():
    print('This is a function')
    a = 1+2
    print(a)

上面我们定义了一个名字为function 的函数,函数没有接收参数,所以括号内部为空,紧接着就是 函数的功能代码。如果执行该脚本,发现并没有输出任何输出,因为我们只定义了函数,而并没有执行函数。 这时我们在 Python 命令提示符中输入函数调用 function(), 注意这里调用函数的括号不能省略。那么 函数内部的功能代码将会执行,输出结果:

This is a function
3

带参定义函数

语法

def function_name(parameters):
    expressions

实例

def func(a, b):
    c = a+b
    print('the c is ', c)

在这里定义的一个函数,其参数就是两个数值,函数的功能就是把两个参数加起来。运行脚本后,在 Python 提示符内调用函数 func, 如果不指定参数 func(), 那么将会出错; 输出 func(1, 2),将 a=1, b=2 传入函数,输出 the c is 3 。所以在调用函数时候,参数个数和位置一定要按照函数定义。如果我们忘记了函数的参数的位置,只知道各个参数的名字,可以在 函数调用的过程中给指明特定的参数 func(a=1, b=2), 这样的话,参数的位置将不受影响,所以 func(b=2,a=1)是同样的 的效果。

函数默认参数

语法

def function_name(para_1,...,para_n=defau_n,..., para_m=defau_m):
    expressions

函数声明只需要在需要默认参数的地方用=号给定即可, 但是要注意所有的默认参数都不能出现在非默认参数的前面。

实例

在这里定义了一个 sale_car函数,参数为车的属性,但除了 price 之外,像 color, brand和 is_second_hand都是有默认值的,如果我们调用函数 sale_car(1000), 那么与 sale_car(1000, ‘red’, ‘carmy’, True)是一样的效果。当然也可以在函数调用过程中传入特定的参数用来修改默认参数。通过默认参数可以减轻我们函数调用的复杂度。

def sale_car(price, color='red', brand='carmy', is_second_hand=True):
    print('price', price,
          'color', color,
          'brand', brand,
          'is_second_hand', is_second_hand,)

注意:默认值放在非默认值之后

作者:SpareNoEfforts
链接:https://www.jianshu.com/p/20d1b512b8b2
来源:简书

self

我们知道,面向对象最重要的概念就是类(class)和实例(instance),类是抽象的模板,比如学生这个抽象的事物,可以用一个Student类来表示。而实例是根据类创建出来的一个个具体的“对象”,每一个对象都从类中继承有相同的方法,但各自的数据可能不同。
1、以Student类为例,在Python中,定义类如下:

class Student(object):
    pass

(Object)表示该类从哪个类继承下来的,Object类是所有类都会继承的类。

2、当然,这样定义的类没有包含任何预定义的数据和功能。除了名字叫Student以外,它没有体现出任何“学生”应该具有的特点。但它是可用的,上述代码运行过后,通过类似

stu_1 = Student()

这样的语句,我们可以创建一个“学生”实例,即一个具体的“学生”对象。通过class语句定义的类Student,就好像一个“模具”,它可以定义作为一个学生应该具有的各种特点(这里暂未具体定义);
而在类名Student后加圆括号(),组成一个类似函数调用的形式Student(),则执行了一个叫做实例化的过程,即根据定义好的规则,创建一个包含具体数据的学生对象(实例)。为了使用创建的学生实例stu_1,我们可以继续为它添加或修改属性,比如添加一组成绩scores ,由三个整数组成:

stu_1.scores = [80, 90, 85]

3、但这样明显存在很多问题,一旦我们需要处理很多学生实例,比如stu_2, stu_3, …,这样不但带来书写上的麻烦,还容易带来错误,万一某些地方scores打错了,或者干脆忘记了,相应的学生实例就会缺少正确的scores属性。更重要的是,这样的scores属性是暴露出来的,它的使用完全被外面控制着,没有起到“封装”的效果,既不方便也不靠谱。一个自然的解决方案是允许我们在执行实例化过程Student()时传入一些参数,以方便且正确地初始化/设置一些属性值,那么如何定义这种初始化行为呢?答案就是在类内部定义一个__init__函数。这时,Student的定义将变成(我们先用一段注释占着__init__函数内的位置)。

class Student():
    def __init__(self, score1, score2, score3):
        # 相关初始化语句

定义__init__后,执行实例化的过程须变成Student(arg1, arg2, arg3),新建的实例本身,连带其中的参数,会一并传给__init__函数自动并执行它。所以__init__函数的参数列表会在开头多出一项,它永远指代新建的那个实例对象,Python语法要求这个参数必须要有,而名称随意,习惯上就命为self。

新建的实例传给self后,就可以在__init__函数内创建并初始化它的属性了,比如之前的scores,就可以写为

class Student():
    def __init__(self, score1, score2, score3):
        self.scores = [score1, score2, score3]

此时,若再要创建拥有具体成绩的学生实例,就只需

stu_1 = Student(80, 90, 85)

此时,stu_1将已经具有设置好的scores属性。并且由于__init__规定了实例化时的参数,若传入的参数数目不正确,解释器可以报错提醒。你也可以在其内部添加必要的参数检查,以避免错误或不合理的参数传递。

4、__init__就与普通函数区别

独立的命名空间,也就是说函数内新引入的变量均为局部变量,新建的实例对象对这个函数来说也只是通过第一参数self从外部传入的,故无论设置还是使用它的属性都得利用self.<属性名>

如果将上面的初始化语句写成scores = [score1, score2, score3](少了self.),
则只是在函数内部创建了一个scores变量,它在函数执行完就会消失,对新建的实例没有任何影响;

与此对应,self的属性名和函数内其他名称(包括参数)也是不冲突的,所以你可能经常见到类似这种写法,它正确而且规范。

class Student():
    def __init__(self, name, scores):
        # 这里增加了属性name,并将所有成绩作为一个参数scores传入
        # self.name是self的属性,单独的name是函数内的局部变量,参数也是局部变量
        self.name = name
        if len(scores) == 3:
            self.scores = scores
        else:
            self.scores = [0] * 3

从第二参数开始均可设置变长参数、默认值等,相应地将允许实例化过程Student()中灵活地传入需要数量的参数;

注意:说到最后,__init__还是有个特殊之处,那就是它不允许有返回值。如果你的__init__过于复杂有可能要提前结束的话,使用单独的return就好,不要带返回值。

作者:追远·J
链接:https://www.zhihu.com/question/46973549/answer/767530541
来源:知乎

5、既然Student类实例本身就拥有这些数据,那么要访问这些数据,就没必要从外面的函数去访问,而可以直接在Student类的内部定义访问数据的函数(方法),这样,就可以把”数据”封装起来。这些封装数据的函数是和Student类本身是关联起来的,称之为类的方法:

class Student(obiect):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print "%s: %s" % (self.name, self.score)
>>>student = Student("Hugh", 99)
>>>student.print_score
Hugh: 99

这样一来,我们从外部看Student类,就只需要知道,创建实例需要给出name和score。而如何打印,都是在Student类的内部定义的,这些数据和逻辑被封装起来了,调用很容易,但却不知道内部实现的细节。

————————————————
版权声明:本文为CSDN博主「CLHugh」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CLHugh/article/details/75000104

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值