Day05

1.文档字符串

(1).help()函数

​ help()是Python中的内置函数,可以查询Python中函数的用法。

help(print)

(2).文档字符串(doc str)

​ 文档字符串就是函数的说明,在定义函数时,可以在函数内部编写文档字符串,可以通过help()函数来查看函数的说明,其实就是在函数的第一行写一个字符串。

​	1.形参后面加:表示形参指定的类型。

​	2.函数后面加->表示该函数的返回值。
def fn(a:int,b:bool) -> int:
    '''
    :param a: int
    :param b: bool
    :return: int
    '''
    return 1

help(fn)

2.作用域

​ 作用域指的就是变量生效的区域。在Python中有两种作用域,分别是全局作用域和函数作用域。

(1).全局作用域

​	1.全局作用域在程序执行时创建,在程序执行结束时销毁。

​	2.所有函数以外的区域都是全局作用域。

​	3.在全局作用域中定义的变量都属于全局变量,可以在程序的任意位置被访问。

(2).函数作用域

​	1.函数作用域在函数调用时创建,在调用结束时销毁。

​	2.函数每调用一次就会产生一个新的函数作用域。

​	3.在函数作用域中定义的变量都是局部变量,只能在函数内部被访问。

(3).查找变量

​	1.当使用变量时,会优先在当前作用域中查找该变量,如果有则使用,如果没有则继续去上一级作用域中查找,以此类推,如果查找到全局作用域依然没有,则会抛出异常。

​	2.在函数中为变量赋值时,默认都是为局部变量赋值,如果需要在函数内部修改全局变量,则需要使用global关键字来声明变量,此时修改的就是全局变量。
a = 10

def fn():
    global a
    a += 10
    print(a)
fn()

3.命名空间(namespace)

​	1.命名空间实际上是一个专门用来存储变量的字典,可以使用locals()获取当前作用域的命名空间。如果在全局作用域中调用locals()则获取全局命名空间,如果在函数作用域中调用locals()则获取函数命名空间,其返回值是一个字典。

​	2.globals()函数可以用来在任意位置获取全局命名空间。

4.递归

​ 简单理解就是函数自己调用自己。递归是解决问题的一种方式,整体思想是将一个大问题分解成若干小问题,直到问题无法分解时再去解决问题。

​ 递归的两个条件:

​	1.基线条件:问题被分解成最小问题,当满足基线条件时,递归就不再执行。

​	2.递归条件:将问题继续分解的条件。

​ 创建一个函数,可以用来求任意数的阶乘。

def factorial(n):
    '''
    该函数用来求任意数的阶乘
    :param n: int
    :return: result
    '''
    if n == 1:
        return 1
    if n > 1:
        return (n * factorial(n - 1))

print(factorial(10))

​ 创建一个函数,检查指定的字符串是否是回文字符串。

def hui_wen(s):
    '''
    该函数用来检查指定的字符串是否是回文字符串,如果是返回True,如果不是返回False
    :param s: 要检查的字符串
    :return: True or False
    '''
    length = len(s)
    if length < 2:
        return True
    elif s[0] != s[-1]:
        return False
    return hui_wen(s[1:-1])

print(hui_wen('abcba'))

5.高阶函数

​ 在Python中,函数是一等对象。一等对象一般都会具有如下特点:

​	1.对象是在运行时创建的。

​	2.能赋值给变量或作为数据结构中的元素。

​	3.能作为参数传递。

​	4.能作为返回值返回。

​ 高阶函数指的是接收函数作为参数或者将函数作为返回值的函数,其至少要符合以下两个特点中的一个:

​	1.接收一个或多个函数作为参数。

​	2.将函数作为返回值返回。

(1).匿名函数

​ 接收函数作为参数。

1->.filter()函数

​ filter()函数可以从序列中过滤出符合条件的元素,保存到一个新的序列中。

​ 其参数有函数(根据该函数来过滤序列)和需要过滤的序列,其返回值是过滤后的新序列。

filter(fn1,l)
2->.匿名函数lambda函数表达式

​ lambda函数表达式专门用来创建一些简单的函数,是函数创建的一种方式,匿名函数一般都是作为参数使用,其语法是:

lambda 参数列表:返回值

def fn(a,b):
    return a + b

lambda a,b:a + b
3->.map()函数

​ map()函数可以对可迭代对象中所有元素做指定操作,然后将其添加到一个新的对象中返回。

l = [1,2,3,4,5]

r = map(lambda i : i + 1,l)
print(list(r))
4->.sort()

​ sort()方法用来对列表中的元素进行排序。其默认是直接比较列表中元素的大小,在sort()可以接收一个关键字参数key,key需要一个函数作为参数。当设置了函数作为参数,每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小。

l = ['aa','b','cccc','ddd']
l.sort(key=len)
print(l)

​ sorted()函数的用法和sort()基本一致,但是sorted()可以对任意的序列进行排序,并且不会影响到原来的对象,而是返回一个新对象。

l = '11467892346802348'
print(sorted(l,key=int))
print(l)

(2).闭包

​ 将函数作为返回值返回,这种高阶函数称为闭包,通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有数据隐藏在闭包中。

def fn():
    a = 10
    def fn1():
        print('fn1函数',a)
    return fn1

"""
r是一个调用fn()后返回的函数。因为该函数在fn()内部被定义,所以该函数总是能够访问到fn()函数内部的变量"""
r = fn()
r()

​ 形成闭包的条件:

​	1.函数嵌套

​	2.将内部函数作为返回值返回

​	3.内部函数必须要使用到外部函数的变量
def make_average():
    nums = []

    def average(n):
        nums.append(n)
        return sum(nums) / len(nums)

    return average

averager = make_average()

print(averager(20))

(3).装饰器

​ 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展,在开发中,都是通过装饰器来扩展函数的功能。在定义函数时,可以通过@装饰器来使用指定的装饰器用来装饰当前的函数,可以同时为一个函数指定多个装饰器,这样函数将会按照从内向外的顺序被装饰。

6.面向对象(OOP)

​ Python是一门面向对象的编程语言,面向对象语言中的所有操作都是通过对象来进行的。面向对象的编程语言关注的是对象而不是过程。面向对象的编程思想将所有的功能统一保存到对应的对象中,要使用某个功能,直接找到对应的对象即可。这种方式编写的代码比较容易阅读,并且比较易于维护,容易复用。

7.类(class)

(1).类的简介

​ 简单理解类就相当于对象的图纸,在程序中需要根据类来创建对象,也成对象是类的实例(instance),如果多个对象是通过一个类创建的,则称这些对象是一类对象。

​ 自定义的类都需要使用大写字母开头,使用大驼峰命名法来对类进行命名。

class MyClass():
    pass
  
mc = MyClass() # mc就是通过MyClass创建的对象,mc是MyClass的实例

result = isinstance(mc,MyClass) # 用来检查一个对象是否是一个类的实例,如果是返回True,否则返回False

(2).使用类创建对象的流程

​	1.创建一个变量

​	2.在内存中创建一个新对象

​	3.init方法执行

​	4.将对象的id赋值给变量
class MyClass():
    pass

mc = MyClass()

​ 此时通过MyClass这个类创建的对象是一个空对象,可以向对象中添加变量,对象中的变量称为属性。语法是:

对象.属性名 = 属性值

(3).类的定义

​ 类和对象都是对现实生活中的事物或程序中内容的抽象。

​ 在类的代码块中,可以定义变量和函数,其会成为所有实例的公共属性,所有实例都可以访问这些变量(对象.属性名)。在类中也可以定义函数,类中定义的函数称为方法,这些方法可以通过该类的所有实例来访问(对象.方法名())。

​ 调用函数时传递几个参数,就会有几个实参,方法调用时,默认会传递一个参数,所以方法中至少要定义一个形参。

(4).属性和方法

​ 当调用一个对象的属性时,解析器会先在当前对象中寻找是否含有该属性。如果有,则直接返回当前的对象的属性值,如果没有,则去当前对象的类对象中寻找,如果有则返回类对象的属性值,如果没有则报错。

​ 如果这个属性或方法是所有的实例共享的,则应将其保存到类对象中;如果这个属性或方法是某个实例独有的,则应该保存到实例对象中。一般情况下,属性保存到实例对象中,而方法需要保存到类对象中。

​ 方法每次被调用时,解析器都会自动传递第一个实参,就是调用方法的对象本身,一般会将这个参数命名为self。

(5).init方法

​ 在类中可以定义一些特殊方法,特殊方法将会在特殊的时刻自动调用。

​ init()会在对象创建以后立即执行,可以用来新创建的对象中初始化属性。调用类创建对象时,类后边的所有参数都会依次传递到init()中。

(6).类的基本结构

class 类名([父类]):
		公共的属性
		# 对象的初始化方法
		def _init_(self,...):
				...
		# 其他的方法
		def method_1(self,...):
				...
        
class Dog:
    def __init__(self,name,age,gender,height):
        self.name = name
        self.age = age
        self.gender = gender
        self.height = height

    def jiao(self):
        print('%s 叫'%self.name)
    def yao(self): 
        print('%s 咬'%self.name)
    def run(self):
        print('%s 跑'%self.name)

d = Dog('小黑',10,'男',20)
print(d.name,d.age,d.gender,d.height)
d.jiao()
d.yao()
d.run()

8.封装

(1).封装的定义

​ 封装指的是隐藏对象中一些不希望被外部所访问到的属性或方法。将对象的属性名修改为一个外部不知道的名字即可隐藏该属性。在外部可以使用getter(get_属性名)和setter(set_属性名)方法来获取和设置对象中指定属性。

​ 使用封装增加了类的定义的复杂程度,但是确保了数据的安全性,其隐藏了属性名,使调用者无法随意修改对象中的属性,增加了getter和setter方法,很好的控制了属性是否是只读的。

​ 如果希望属性可读,则可以直接去掉setter方法,如果希望属性不能被外部访问,则可以直接去掉getter方法。

​	1.使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的。

​	2.使用getter方法获取属性,使用setter方法设置属性,可以在读取和修改属性的同时做一些其他的处理。
class Dog:
    '''
    表示狗的类
    '''
    def __init__(self,name,age):
        self.hidden_name = name
        self.hidden_age = age
        def say_hello(self):
            print('大家好,我是%s' %self.hidden_name)

        def get_name(self):
            print('用户读取了属性')
            return  self.hidden_name

        def set_name(self):
            print('用户修改了属性')
            self.hidden_name = name
            
        def get_age(self):
            return self.hidden_age
        
        def set_age(self,age):
            if age > 0:
                self.hidden_age = age
            else:
                print('输入的年龄不合法')

(2).隐藏类中的属性

​ 可以为对象的属性使用双下划线开头,__xxx,双下划线开头的属性是对象的隐藏属性,只能在类的内部访问,无法通过对象访问。使用双下划线开头的属性,实际上依然可以在外部访问,所以这种方式一般不使用。一般会将一些私有属性(不希望被外部访问的属性)以下划线开头。

​ 一般情况下,使用下划线开头的属性都是私有属性,没有特殊需要不要修改私有属性。

(3).property装饰器

​ property装饰器用来将一个get方法转换为对象的属性,添加为property装饰器后,可以像调用属性一样使用get方法。使用property装饰的方法,其方法名必须和属性名一致。

​ @属性名.setter是setter方法的装饰器

class Person:
    def __init__(self,name):
        self._name = name

    @property
    def name(self):
        return self._name
    
    @name.setter
    def name(self,name):
        self._name = name

你可能感兴趣的:(Python,python,开发语言)