【整理】Python学习笔记1.4

第四章 函数与对象


     函数是将一些语句集合在一起,使其能够反复在程序中运行。对象则可以视作数据及一系列可存取、操作这些数据的方法所组成的集合,反映了“万物皆对象”的理念。

敲黑板的重点终于来了!!!

说得我会信一样

函数

     函数可分为内置函数、自定义函数与匿名函数。(函数千千万,不行咱就换)

内置函数

  1. 与数据对象相关的函数:主要是定义数据类型。如int 创建十进制整数; dict 创建字典; tuple 创建元组等。
  2. 数学计算函数:如max 返回最大值或参数的最大值; min 返回最小值或参数的最小值; sum 求和; abs 求绝对值; pow 返回幂运算值或模值; round 对float四舍五入; divmod 返回两个数值的商和余数。
  3. 与str相关的函数:这里函数主要提供str的输出和编译功能 如:format 格式化显示值; compile 编译str为代码,使之能执行; eval 执行动态表达式求值; exec 执行动态语句块; repr 返回对象的str形式。
  4. 与序列对象相关的函数:这类函数执行后往往返回经过改造的序列对象,或生成不同形式的序列对象。

    如enumerate函数将一个可遍历的数据对象组合为一个索引序列,同时标出数据和数据下标,一般用在for循环中; filter函数用于过滤序列中不符合条件的元素,返回由符合条件组成的新的list; map函数根据提供的函数对指定序列做映射; zip函数将可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple,然后返回由这些tuple组成的list。
  5. I/O功能函数:必须掌握。如input 交互式输入; print 打印输出; open 打开文件; close 关闭文件; read 读取文件内容; write 将内容写入文件
  6. 用于查询与判断的函数:如type 查询对象类型,或创建新类型; isinstance 判断对象是否是已知类。
  7. 其他内置函数:如help 返回对象的帮助信息; import 动态导入模块。

自定义函数

     在Python中,一般使用 def语句 自定义函数。
     def语句的首行包括标识符def、函数名和圆括号,任何传入的参数都放在圆括号中; 之后为函数的执行体,以冒号启始。换行缩进; 如果函数有返回值,则以return表达式结束函数,不带return表达式的情况相当于返回None值。执行体的内容不能为空,至少用pass语句来表示空语句,否则函数将无法执行。

def function(part1, part2, ...):
    suite
    return expression

     函数的参数主要有3大类,分别是:位置和关键字参数; 任意数量的位置参数; 任意数量的关键字参数。第一类参数又称定长参数、不可变参数,第2、3类参数又称为不定长参数、可变参数。

     (1)位置参数和关键字参数是Python默认的参数类型。位置参数的形式往往是简单的数字,数字的排序是有意义的,代表了参数的位置; 关键字参数则类似于dict中的元素,关键字与值成对出现,值具有对应的关键字,没有位置的概念。混合使用位置参数和关键字参数时,位置参数必须在关键字参数的前面。

def  func1(a, b = 2):
    print(a, b)
func1(1)
1 2

(代码规则:有默认值参数需在无默认值参数后)

     (2) 不定数量的位置参数在定义时需要加一个星号(*)前缀,传递参数时可以在原有参数的后面添加零个或多个参数,这些参数将会被放在tuple内并传入函数。带星号前缀的参数必须定义在不带星号的参数之后。

def  func2(string, *numbers):
    print(string, numbers)
func2('numbers:', 1, 2, 3)
numbers: (1, 2, 3)

     (3) 在定义不定数量的关键字参数时,其参数名称前需要加两个星号(**)作为前缀,这样定义出来的参数,在传递参数时,可以在原有的参数后面添加任意零个或多个关键字参数。

def  func3(a, *numbers, **kwargs):
    print (a, numbers, kwargs)
func3(4, 2, 3, 4, b = 2, c = 3)
4 (2, 3, 4) {'b': 2, 'c': 3}

     在模块中创建或调用函数,会生成一个嵌套的名字空间,称为函数的作用域。作用域使得函数中的名字不会与模块中或其他函数中的名字冲突。因此可以说:函数定义了局部的作用域,而模块定义了全局的作用域。

Python的名字解析被称为 LGB规则,该规则包含3点内容。

  1. 当在函数中使用一个无限制的名字时,Python依次查找3个作用域:局部的(Local)、全局的(Global)、内置的(Built-in),在第1个发现名字的位置停止。
  2. 在函数中赋值一个名字时,Python总在局部作用域中生成或改变它,除非在函数中对它进行了全局声明。
  3. 在函数外部时,局部作用域与全局作用域等效,都是一个模块的名字空间。

匿名函数

     所谓匿名函数,即没有具体名称的函数。在Python中,可以用lambda语句来创建匿名函数,lambda的主体是一个表达式,而不是一个代码块,用其创建函数比使用def语句创建要简单很多。基本语法格式如下:

f = lambda par1,... ,parn:exp
# par:表示参数    exp:表示输出值计算表达式

     匿名函数也是一个函数对象,因此可以把匿名对象赋值给一个变量,再利用变量调用该函数。

square = lambda x: x * x
squ = square(5)
print('5的平方为:', squ)
5的平方为: 25

     匿名函数的优势在于:编写脚本时可省去定义函数的过程,使代码变得精简; 对于一些抽象的、不会在其他地方复用的函数,给一个函数命名也是难题(需避免重名),创建匿名函数不需要考虑函数命名的问题。

# 使用def语句
def f(x):
    return x * x
print(list(map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])))

# 使用lambda语句
print(list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[1, 4, 9, 16, 25, 36, 49, 64, 81]

(3行 VS 1行)

对象

     在计算机科学领域里,对象指的是一个拥有值的存储器地址,通常有一个标识符指向该地址。变量、数据结构或者函数都可以称为一个对象。面向对象中最重要的概念是类和实例,对象是类的实例,每个对象可认为是一个特定类的实例。

悄悄:当你没有对象时,可以new一个对象,前提是你要找到你的类

狗头

     在Python中,类通过关键字class定义,格式如下:

#"ClassName"为类名,通常按驼峰命名法命名
class classname:
    <statement-1>
    ...
    <statement-N>

     举个例子:

class Car:
    def out(self):
        print('This is a Car')
# 实例化类
car = Car()
print('实例化的Car类:', car)

# 调用类内部函数
car.out()
实例化的Car类: <__main__.Car object at 0x01611448>
This is a Car

属性与方法

     类中包含属性与方法,类属性可从外部进行引用和操作,类方法也可以从外部调用。

     类中封装的变量被称为类属性,类属性是类对象所拥有的属性,它被所有类对象的实例对象所共有, 在内存中只存在一个副本,这与C++、Java中类的静态成员变量有些类似。一个类实例化后生成的实例也拥有该属性,针对实例属性的操作并不会影响类属性本身,修改实例属性的值并不会影响原本的类属性的值,删除实例属性后,原本的类属性将显现出来。

     在Python中,采用 __init__()方法,通过该方法在创建实例的时候将需要绑定的属性写进类中,会使得类更加模块化。从而从外部创建实例时只需传入规定的数据,外部直接调用类中的方法即可查看到结果。
     举个例子:

class Student():
    def __init__(self, name, id, gender, score):
        self.name = name
        self.id = id
        self.gender = gender
        self.score = score
        
    def get_name(self):
        print('学生姓名:', self.name)
        
    def get_score(self):
        print('成绩:', self.score)
# 实例化并传入数据
john = Student('John', '310800123', 'male', 96)
john.get_name()
john.get_score()
学生姓名: John
成绩: 96

访问权限

     由于外部代码可通过实例属性直接操作数据,为避免被外部错误引用,可创建私有的类属性,私有类属性为对类中数据的封装。私有类属性分为两种,一种为“_attributename”,这种私有属性名称前仅有一个下划线,仅声明该属性为私有属性,外部仍可调用;另一种为“__attributename”,这种私有属性名称前有两个下划线,无法从类外部调用。

# 将name属性完全私有化,score属性仅声明为私有属性
class StudentNew():
        def __init__(self, name, id, gender, score):
            self.__name = name
            self.id = id
            self.gender = gender
            self._score = score
# 实例化并查看属性
john = StudentNew('John', '310800123', 'male', 96)
print('id属性为:', john.id)

print('声明私有化的score属性为:', john._score)

# 完全私有化的属性,外部调用时将报错
john.__name
id属性为: 310800123

声明私有化的score属性为: 96

Traceback (most recent call last):
  File "C:\Users\Lenovo\Desktop\pyscript\1.py", line 20, in <module>
    john.__name
AttributeError: 'StudentNew' object has no attribute '__name'

     方法:自定义函数通过def语句定义,类中的函数也通过def语句定义。类中封装的函数被称为方法,与一般函数不同之处为,方法中第1个参数为“self”参数,通常不能省略,改参数指向实例本身,调用方法时不需要传入该参数。

     使用dir函数可以查看一个对象的所有属性和方法,返回的内容包含在一个list中。

#查看string对象的所有属性和方法
print('string对象的属性与方法为:\n',dir('a'))
string对象的属性与方法为:
 ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

装饰器

(不太懂,不展开)

     装饰器本质上是一个Python函数或类,可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用。装饰器的作用是为已经存在的对象添加额外的功能。
     函数也作为一个对象,且拥有名称属性,可通过“__name__”获取。
     类中的装饰器常用的有3种:@staticmethod,@classmethod和@property 。

继承和多态

     面向对象编程的一个重要特征是继承,在类中体现为,新建一个类时可以从现有的类进行继承,此时新建的类称为子类,被继承的类称为父类、基类或超类。

     继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。 在令子类继承父类的同时,还可重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。子类不仅可以继承一个父类的属性和方法,还可以同时继承多个父类的属性和方法,这便是多重继承。

     super不仅可以调用父类的__init__()方法,也可调用其他的一般方法,语法格式如下:

super([type[, object-or-type]])

     举个例子:

# Transpotation类中的__init__方法和run方法
class Transpotation():
    def __init__(self):
        self.length = 191

    def run(self):
        print('Transpotation is running')


# 在Airplane类中定义__init__方法和fly方法
class Airplane(Transpotation):
    def __init__(self):
        self.high = 18

    def fly(self):
        print('Airplane is flying')


plane = Airplane()
print('Airplane类中的high属性为:', plane.high)

#plane.length  # __init__方法被重写,属性被覆盖,将报错

plane.fly()


# 使用super函数重写Airplane类中的方法
class Airplane(Transpotation):
    def __init__(self):
        self.high = 18
        super().__init__()

    def fly(self):
        print('Airplane is flying')
        super().run()


# 父类的属性可被调用
plane1 = Airplane()
print('父类Transpotation类的length属性为:', plane1.length)

# 父类的run方法的功能已添加进fly方法中
plane1.fly()
Airplane类中的high属性为: 18
Airplane is flying

父类Transpotation类的length属性为: 191
Airplane is flying
Transpotation is running

第三方库安装

(简单记一下)
     1. 使用pip安装; 2.使用easy_install安装; 3.使用源文件安装; 4.通过安装包安装。(可参照网络教程进行操作)

#pip常用命令

#安装包
pip install xxx

#升级包,可以用-U或者--upgrade
pip install -U xxx

#卸载包
pip unistall xxx

#列出已安装包
pip list

     Python提供了4种导入第三方库的方法,分别为:使用import语句导入、使用别名导入、使用from…import…语句导入、通过内建函数_import_()导入。

     要从给定的模块中导入特定的函数或对象,可以使用from import语句。该语句在当前的名称空间建立一个用到该模块的引用,引用时必须使用全称,使用在被导入模块中定义的函数时必须包含模块的名字。该语句支持从一个模块中导入多个函数或类,如:

from mod_name import func_name1,func_name2, ... ,func_nameN

     导入自定义模块的方式有3种:直接import,通过sys模块导入自定义模块的路径,通过pth文件找到自定义模块。

第四章课后题概述

  1. B
    其他选项均有反置表述;正确的依次为 bytes函数创建不可变字节数组,bytearray 函数创建可变字节数组; exec函数执行动态语句块,eval函数执行动态表达式求值; any函数判断是否有为True的元素,all函数判断每个元素是否都为True

  2. D
    lambda语句也支持嵌入简单的结构体,如构建一个包含分支结构的lambda语句如下:f1 = lambda x: ‘传入的参数为1’’ if x == 1 else ‘传入的参数不为1’

  3. A
    修改实例属性不会影响原本的类属性

  4. C
    子类可以继承多个父类的属性和方法

  5. C
    采用__import__()函数即可

  6. 填空题
    1)自定义函数的参数分为3大类。分别是位置和关键字参数、不定数量的位置参数、不定数量的关键字参数。
    2)在lambda语句中,冒号之前是函数参数,冒号之后是返回值
    3)类中的一般方法的第1个参数是self参数,类方法的第1个参数是cls
    4)可在创建实例时将属性绑定进类中的特殊方法是__init__(),可返回对象长度的特殊方法是__len__()
    5)创建第三方库的过程,本质上就是将写好的模块以库的形式按照一定的规则组合起来的过程。

  7. 算式判定:def语句和lambda语句的对比

def func1(x, y):
    print(x ** 5 == y ** 2 - 1)
    return
func1(3, 12)

func2 = lambda x, y : print(x ** 5 == y ** 2 - 1)
func2(3, 12)
False
False
  1. 父类与子类:动物
# 定义父类
class Animal(object):
    def eat(self):
        print("%s eating" % (self.name))
    def drink(self):
        print("%s drinking" % (self.name))
        
# 定义子类
class Bird(Animal):
    def __init__(self,name):
        self.name = name
    def fly(self):
        print("Bird fly")

class Fish(Animal):
    def __init__(self,name):
        self.name = name
    def swim(self):
        print("Fish swim")

# 查看子类继承的属性,并调用子类中的方法
bird1 = Bird("xiaofei")
bird1.fly()
bird1.eat()

fish1 = ("xiaobai")
fish1.swim()
fish1.drink()
Bird fly
xiaofei eating

Fish swim
xiaobai drinking
  1. 导入math模块
import math
a = math.exp(2)
b = math.pi
print('e²+π=', a+b)
+π= 10.530648752520444

     注:代码除部分经本人修改外,主要来自 机械工业出版社的《Python3智能数据分析快速入门》 的配套资料。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值