Python基础入门教程(下)

news2024/11/17 11:23:01

目录

七、函数进阶

7.1、函数多返回值

7.2、函数多种传参方式

位置参数

关键字参数

缺省参数

不定长参数

位置传递

关键字传递

7.3、匿名函数

函数作为参数传递

lambda匿名函数

八、文件操作

8.1、文件的读取

open()打开函数

mode常用的三种基础访问模式

读操作相关方法

read()方法

readlines()方法

readline()方法

for循环读取文件行

close() 关闭文件对象

8.2、文件的写入

8.3、文件的追加

九、异常、模块与包

9.1、什么是异常?

9.2、异常的捕获方法

捕获常规异常

捕获指定异常

捕获多个异常

捕获异常并输出描述信息

捕获所有异常

异常else

异常的finally

9.3、异常的传递

9.4、Python模块

模块的导入

什么是模块?

模块的导入方式

import模块名

from 模块名 import 功能名

from 模块名 import *

as定义别名

自定义模块

制作自定义模块

测试模块

__all__

9.5、Python包

快速入门

导入包

方式一

方式二

安装第三方包

安装第三方包 - pip

pip的网络优化

安装第三方包 - PyCharm

9.6、JSON运用

十、面向对象

10.1、初始对象

10.2、成员方法

什么是类?

成员变量和成员方法

成员方法的定义语法

10.3、构造方法

10.4、其它内置方法

魔术方法

__str__ 字符串方法 

__lt__ 小于符号比较方法

__le__ 小于等于比较符号方法

__eq__比较运算符实现方法

10.5、封装

面向对象的三大特性

私有成员 

10.6、继承

单继承

多继承

调用父类同名成员

10.7、类型注解

变量的类型注解

基础数据类型注解

类对象类型注解

基础容器类型注解

容器类型详细注解

类型注解的语法

函数(方法)的类型注解

形参注解

返回值注解

union类型

10.8、多态

什么是多态?

抽象类(接口)

十一、操作SQL

11.1、基本操作

11.2、插入数据

11.3、查询数据

十二、PySpark

12.1基础准备

PySpark库的安装

构建PySpark执行环境入口对象

12.2、数据输入

RDD对象

Python数据容器转RDD对象

读取文件转RDD对象

12.3、数据计算

map方法

flatMap方法

reduceByKey方法

filter方法

distainct方法

sortBy方法

12.4、数据输出

collect方法

take方法

count方法


七、函数进阶

7.1、函数多返回值

如果一个函数要有多个返回值,该如何书写代码?

def test_return():
    return 1, 2

x, y = test_return()
print(x) # 1
print(y) # 2

按照返回值的顺序,写对应顺序的多个变量接收即可。

变量之间用逗号隔开。

支持不同类型的数据return。

7.2、函数多种传参方式

位置参数

位置参数:调用函数时根据函数定义的参数位置来传递参数

def user_info(name, age, gender):
    print(f"您的名字是{name},年龄是{age},性别是{gender}")

user_info('TOM', 30, '男')

注意:传递的参数和定义的参数的顺序及个数必须一致。

关键字参数

关键字参数:函数调用时通过“键=值”形式传递参数。

作用:可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

def user_info(name, age, gender):
    print(f"您的名字是{name},年龄是{age},性别是{gender}")

user_info(gender='男', name='Jerry', age=20)

注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。

缺省参数

缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)

作用:当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.

def user_info(name, age, gender='男'):
    print(f"您的名字是{name},年龄是{age},性别是{gender}")

user_info(name='Jerry', age=20) # 您的名字是Jerry,年龄是20,性别是男

注意:函数调用时,如果为缺省参数传值则修改默认参数值, 否则使用这个默认值。

不定长参数

不定长参数:不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。

作用:当调用函数时不确定参数个数时, 可以使用不定长参数。

不定长参数的类型:

        ①位置传递

        ②关键字传递

位置传递

def user_info(*args):
    print(args)

user_info('TOM', 20) # ('TOM', 20)

注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递。

关键字传递

def user_info(**kwargs):
    print(kwargs)

user_info(name='TOM', age=20, school='哈尔滨工业大学') # {'name': 'TOM', 'age': 20, 'school': '哈尔滨工业大学'}

注意:参数是“键=值”形式的形式的情况下,所有的“键=值”都会被kwargs接受,同时会根据“键=值”组成字典。

7.3、匿名函数

函数作为参数传递

在前面的函数学习中,我们一直使用的函数,都是接受数据作为参数传入: 数字 字符串 字典、列表、元组等。其实,我们学习的函数本身,也可以作为参数传入另一个函数内。

def compute(x, y):
    return x + y

def test_func(compute):
    result = compute(1, 2)
    print(result)

test_func(compute) # 3

lambda匿名函数

函数的定义中:

  • def关键字,可以定义带有名称的函数
  • lambda关键字,可以定义匿名函数(无名称)

有名称的函数,可以基于名称重复使用

无名称的匿名函数,只可临时使用一次

匿名函数定义语法:

lambda 传入参数:函数体(一行代码)

lambda 是关键字,表示定义匿名函数。

传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数。

函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码。

正常写法:

def compute(x, y):
    return x + y

def test_func(compute):
    result = compute(1, 2)
    print(result)

test_func(compute) # 3

lambda匿名写法:

def test_func(compute):
    result = compute(1, 2)
    print(result)

test_func(lambda x,y:x+y) # 3

八、文件操作

8.1、文件的读取

想想我们平常对文件的基本操作,大概可以分为三个步骤(简称文件操作三步走):

① 打开文件

② 读写文件

③ 关闭文件

open()打开函数

在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下:

open(name, mode, encoding)

name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。

mode:设置打开文件的模式(访问模式):只读、写入、追加等。

encoding:编码格式(推荐使用UTF-8)

示例代码:

f = open('python.txt', 'r', encoding=”UTF-8)

注意:encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定。

mode常用的三种基础访问模式

模式

描述

r

以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。

w

打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。

如果该文件不存在,创建新文件。

a

打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。

如果该文件不存在,创建新文件进行写入。

读操作相关方法

read()方法

文件对象.read(num)

num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。

readlines()方法

readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。

f = open('python.txt', 'r', encoding='UTF-8')
content = f.readlines()
print(content) # ['我喜欢学习Java,同时我更爱Python']

# 关闭文件
f.close()

readline()方法

一次读取一行内容。

f = open('python.txt', 'r', encoding='UTF-8')
content = f.readline()
print(content) # 我喜欢学习Java,同时我更爱Python

content = f.readline()
print(content) # 深度学习和机器学习有什么区别呢?

# 关闭文件
f.close()

for循环读取文件行

for line in open('python.txt', 'r', encoding='UTF-8'):
    print(line)

close() 关闭文件对象

f = open("python.txt", "r")

f.close()

# 最后通过close,关闭文件对象,也就是关闭对文件的占用
# 如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用。

8.2、文件的写入

示例代码:

# 打开文件/创建文件
f = open('python1.txt', 'w', encoding='UTF-8')
# 文件写入
f.write('HelloWorld')
# 内容刷新
f.flush()

注意:

  • 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
  • 当调用flush的时候,内容会真正写入文件,这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)。
  • 文件如果不存在,使用”w”模式,会创建新文件。
  • 文件如果存在,使用”w”模式,会将原有内容清空。

8.3、文件的追加

f = open('python.txt', 'a', encoding='UTF-8')
# 文件追加
f.write('计算机视觉是什么?')
f.flush()

 

九、异常、模块与包

9.1、什么是异常?

当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”, 也就是我们常说的BUG。

例如:以`r`方式打开一个不存在的文件。

f = open('python222.txt', 'r', encoding='UTF-8')

9.2、异常的捕获方法

当我们的程序遇到了BUG,那么接下来有两种情况:

        ① 整个程序因为一个BUG停止运行。

        ② 对BUG进行提醒,整个程序继续运行。

显然在之前的学习中,我们所有的程序遇到BUG就会出现①的这种情况,也就是整个程序直接奔溃。

但是在真实工作中,我们肯定不能因为一个小的BUG就让整个程序全部奔溃,也就是我们希望的是达到②的这种情况,那这里我们就需要使用到捕获异常。

捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。

捕获常规异常

基本语法:

try:
    可能发生错误的代码
except:
    如果出现异常执行的代码

快速入门

需求:尝试以`r`模式打开文件,如果文件不存在,则以`w`方式打开。

try:
    f = open('python.txt', 'r', encoding='UTF-8')
except:
    f = open('python.txt', 'w', encoding='UTF-8')

捕获指定异常

基本语法:

try:
    print(name)
except NameError as e:
    print('name变量名称未定义异常')

注意事项:

        ① 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。

        ② 一般try下方只放一行尝试执行的代码。

捕获多个异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。

基本语法:

try:
    print(1/0)
except (NameError, ZeroDivisionError):
    print('ZeroDivision错误...')

捕获异常并输出描述信息

基本语法:

try:
    print(num)
except (NameError, ZeroDivisionError) as e:
    print(e)

捕获所有异常

基本语法:

try:
    print(name)
except Exception as e:
    print(e)

异常else

else表示的是如果没有异常要执行的代码。

try:
    print(1)
except Exception as e:
    print(e)
else:
    print('我是else,是没有异常的时候执行的代码')

异常的finally

finally表示的是无论是否异常都要执行的代码,例如关闭文件。

try:
    f = open('test.txt', 'r')
except Exception as e:
    f = open('test.txt', 'w')
else:
    print('没有异常,真开心')
finally:
    f.close()

9.3、异常的传递

异常是具有传递性的。

函数func01中发生异常,并且没有捕获处理这个异常的时候,异常会传递到函数func02,当func02也没有捕获处理这个异常的时候,main函数会捕获这个异常,这就是异常的传递性。

提示:当所有函数都没有捕获异常的时候,程序就会报错。

9.4、Python模块

模块的导入

什么是模块?

Python 模块(Module),是一个 Python 文件,以 .py 结尾.  模块能定义函数,类和变量,模块里也能包含可执行的代码。

大白话来说,模块就是一个Python文件,里面有类、函数、变量等,我们可以 拿过来用(导入模块去使用)。

模块的导入方式

模块在使用前需要先导入,导入的语法如下:

[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名]

常用的组合形式如:

  • import 模块名
  • from 模块名 import 类、变量、方法等
  • from 模块名 import *
  • import 模块名 as 别名
  • from 模块名 import 功能名 as 别名

import模块名

基本语法:

import 模块名
import 模块名1,模块名2

模块名.功能名()

示例代码:导入time模块

import time

print('start')
# 让程序睡眠1秒
time.sleep(1)
print('end')

from 模块名 import 功能名

基本语法:

from 模块名 import 功能名

功能名()

示例代码:导入time模块中的sleep方法

from time import sleep

print('start')
# 让程序睡眠1秒
sleep(1)
print('end')

from 模块名 import *

基本语法:

from 模块名 import *

功能名()

示例代码:导入time模块中的所有方法

from time import *

print('start')
# 让程序睡眠1秒
sleep(1)
print('end')

as定义别名

基本语法:

# 模块定义别名
import 模块名 as 别名

# 功能定义别名
from 模块名 import 功能 as 别名

示例代码:

import time as t

print('start')
# 让程序睡眠1秒
t.sleep(1)
print('end')
from time import sleep as s1

print('start')
# 让程序睡眠1秒
s1(1)
print('end')

自定义模块

制作自定义模块

Python中已经帮我们实现了很多的模块,不过有时候我们需要一些个性化的模块,这里就可以通过自定义模块实现,也就是自己制作一个模块。

示例代码:新建一个Python文件,命名为my_module1.py,并定义test函数

测试模块

在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果, 这个开发人员会自行在py文件中添加一些测试信息,例如,在my_module1.py文件中添加测试代码test(1,1)。

问题:此时,无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行`test`函数的调用。

解决方案:     

__all__

如果一个模块文件中有`__all__`变量,当使用`from xxx import *`导入时,只能导入这个列表中的元素。

9.5、Python包

从物理上看,包就是一个文件夹,在该文件夹下包含了一个 __init__.py 文件,该文件夹可用于包含多个模块文件。

从逻辑上看,包的本质依然是模块。

包的作用:当我们的模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含多个模块,但包的本质依然是模块。

快速入门

步骤如下:

① 新建包`my_package`

② 新建包内模块:`my_module1` 和 `my_module2`

③ 模块内代码如下

示例代码:

注意:新建包后,包内部会自动创建`__init__.py`文件,这个文件控制着包的导入行为。

导入包

方式一

import 包名.模块名

包名.模块名.目标

方式二

注意:必须在`__init__.py`文件中添加`__all__ = []`,控制允许导入的模块列表。

from 包名 import *

模块名.目标

安装第三方包

安装第三方包 - pip

第三方包的安装非常简单,我们只需要使用Python内置的pip程序即可。

打开我们许久未见的:命令提示符程序,在里面输入:

pip install 包名称

即可通过网络快速安装第三方包。

pip的网络优化

由于pip是连接的国外的网站进行包的下载,所以有的时候会速度很慢。

我们可以通过如下命令,让其连接国内的网站进行包的安装:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

安装第三方包 - PyCharm

9.6、JSON运用

"""
    演示JSON数据和Python字典的相互转换
"""
import json

# json数据
data = [{'name': '米米', 'age': 18}, {'name': '豆豆', 'age': 23}]

# 将JSON对象转为JSON字符串
json_str = json.dumps(data, ensure_ascii=False)

print(json_str) # [{"name": "米米", "age": 18}, {"name": "豆豆", "age": 23}]

# 将JSON字符串转为JSON对象
data = json.loads(json_str)

print(data) # [{"name": "米米", "age": 18}, {"name": "豆豆", "age": 23}]

十、面向对象

10.1、初始对象

什么是对象呢?其实用白话来解释很简单,就是我们日常生活中的人、动物、植物,甚至是桌椅板凳都是对象。

10.2、成员方法

什么是类?

我们上面讲过对象是什么,那类其实就是对象的模板,你想象一下,假如你是女娲,你在造每个人的时候是不是要设置个模板,比如你是眼睛大,厚嘴唇,那就设置一个眼睛大,厚嘴唇的类,然后通过类可以创建无数个对象,这些对象的特征都是眼睛大,厚嘴唇。

语法:

class 类名称:
    类的属性

    类的行为

class是关键字,表示要定义类了。

类的属性,即定义在类中的变量(成员变量)。

类的行为,即定义在类中的函数(成员方法)。

创建类对象的语法:

对象 = 类名称()

成员变量和成员方法

那么,什么是类的行为(方法)呢?

比如我们现在是女娲,我要造一个人,这个人具有学习的行为,那么在造人之前我先设定好模板。

# Person类
class Person:
    name = None
    age = None

    def study(self):
        print(f'我是{self.name},我具有学习的能力')

设定好模板后,我们创建对象,注意,这时才开始创建真正的人。

stu = Person() # 创建人的对象
stu.name = '荀彧'
stu.age = 60
stu.study()

可以看出,类中:

  • 不仅可以定义属性用来记录数据
  • 也可以定义函数,用来记录行为

其中:

  • 类中定义的属性(变量),我们称之为:成员变量
  • 类中定义的行为(函数),我们称之为:成员方法

成员方法的定义语法

在类中定义成员方法和定义函数基本一致,但仍有细微区别:

def 方法名(self, 参数1...参数n):
    方法体

可以看到,在方法定义的参数列表中,有一个:self关键字

self关键字是成员方法定义的时候,必须填写的。

  • 它用来表示类对象自身的意思。
  • 当我们使用类对象调用方法的是,self会自动被python传入。
  • 在方法内部,想要访问类的成员变量,必须使用self
class Person:
    name = None
    age = None

    def study(self):
        print(f'我是{self.name},我具有学习的能力')

注意:self关键字,尽管在参数列表中,但是传参的时候可以忽略它。self是透明的,可以不用理会它。

10.3、构造方法

Python类可以使用:__init__()方法,称之为构造方法。

可以实现:

  • 在创建类对象(构造类)的时候,会自动执行
  • 在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用
class Person:
    name = None
    age = None
    school = None

    # 构造方法
    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school
        print('构造方法执行了')

p = Person('装不满的克莱因瓶', 27, '哈工大')
print(p.name)
print(p.age)
print(p.school)

10.4、其它内置方法

魔术方法

上文学习的__init__ 构造方法,是Python类内置的方法之一。

这些内置的类方法,各自有各自特殊的功能,这些内置方法我们称之为:魔术方法

__str__ 字符串方法 

先看一段代码,我们试着打印一下对象。

class Person:
    name = None
    age = None
    school = None

    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school

p = Person('装不满的克莱因瓶', 27, '哈工大')
print(p) # <__main__.Person object at 0x000002625D84B9A0>

打印的是一串我们看不懂的东西,其实它是对象的内存地址

内存地址没有多大作用,我们可以通过__str__方法,控制类转换为字符串的行为。

class Person:
    name = None
    age = None
    school = None

    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school

    def __str__(self):
        return f"name={self.name},age={self.age},school={self.school}"

p = Person('装不满的克莱因瓶', 27, '哈工大')
print(p) # name=装不满的克莱因瓶,age=27,school=哈工大

__lt__ 小于符号比较方法

class Person:
    name = None
    age = None
    school = None

    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school

    def __str__(self):
        return f"name={self.name},age={self.age},school={self.school}"

    def __lt__(self, other):
        return self.age < other.age

p1 = Person('装不满的克莱因瓶', 27, '哈工大')
p2 = Person('小小康', 20, '北京理工大学')
print(p1 < p2) # False

__le__ 小于等于比较符号方法

class Person:
    name = None
    age = None
    school = None

    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school

    def __str__(self):
        return f"name={self.name},age={self.age},school={self.school}"

    def __le__(self, other):
        return self.age <= other.age

p1 = Person('装不满的克莱因瓶', 27, '哈工大')
p2 = Person('小小康', 20, '北京理工大学')
print(p1 <= p2) # False

__eq__比较运算符实现方法

class Person:
    name = None
    age = None
    school = None

    def __init__(self, name, age, school):
        self.name = name
        self.age = age
        self.school = school

    def __str__(self):
        return f"name={self.name},age={self.age},school={self.school}"

    def __eq__(self, other):
        return self.name == other.name

p1 = Person('装不满的克莱因瓶', 27, '哈工大')
p2 = Person('装不满的克莱因瓶', 20, '北京理工大学')
print(p1 == p2) # True

不实现__eq__方法的话,对象之间可以比较,但是是比较内存地址,也即是:不同对象==比较一定是False结果。

实现了__eq__方法,就可以按照自己的想法来决定2个对象是否相等了。

10.5、封装

面向对象的三大特性

面向对象包含3大主要特性:

  • 封装
  • 继承
  • 多态

封装表示的是,将现实世界事物的:属性,行为。封装到类中,描述为: 成员变量,成员方法。从而完成程序对现实世界事物的描述。

私有成员 

既然现实事物有不公开的属性和行为,那么作为现实事物在程序中映射的类,也应该支持。

类中提供了私有成员的形式来支持:

  • 私有成员变量
  • 私有成员方法

定义私有成员的方式非常简单,只需要:

  • 私有成员变量:变量名以__开头(2个下划线)
  • 私有成员方法:方法名以__开头(2个下划线)

即可完成私有成员的设置

class Person:
    name = None
    age = None
    __school = None # 私有成员变量

    def study(self):
        print('学习')

    def __read(self): # 私有成员方法
        print('阅读')

私有成员无法被类对象使用,但是可以被其它的成员使用。

class Person:
    name = None
    age = None
    __school = None # 私有成员变量

    def study(self):
        self.__read()
        print(self.__school)
        print('学习')

    def __read(self): # 私有成员方法
        print('阅读')


p = Person()
p.study()

10.6、继承

单继承

语法:

class 类名(父类名):
    类内容体

继承表示:将从父类那里继承(复制)来成员变量和成员方法(不含私有)。

示例代码:

class Father:
    name = '曹操'

    def study(self):
        print(f'{self.name}会学习')


class Son(Father):
    name = '曹植'

    def play(self):
        print(f'{self.name}会玩')
        
son = Son()
print(son.name)
son.study()
son.play()

多继承

Python的类之间也支持多继承,即一个类,可以继承多个父类。

语法:

class 类名(父类1,父类2,.....,父类N):
    类内容体

调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。也就是上面的例子,父类有属性叫name,子类也有属性叫name,那调用name属性的时候,肯定是调用的子类的name属性。

如果需要使用被复写的父类的成员,需要特殊的调用方式:

方式1: 调用父类成员      

  • 使用成员变量:父类名.成员变量      
  • 使用成员方法:父类名.成员方法(self)

方式2: 使用super()调用父类成员

  • 使用成员变量:super().成员变量
  • 使用成员方法:super().成员方法()

10.7、类型注解

变量的类型注解

Python在3.5版本的时候引入了类型注解,以方便静态类型检查工具,IDE等第三方工具。

类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。

主要功能:

  • 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示。
  • 帮助开发者自身对变量进行类型注释

基础数据类型注解

var_1: int = 0
var_2: float = 3.14
var_3: bool = True
var_4: str = "Python"

类对象类型注解

class Student:
    pass

stu: Student = Student()

基础容器类型注解

my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_set: set = {1, 2, 3}
my_dict: dict = {'name', 'CLAY'}
my_str: str = 'CLAY'

容器类型详细注解

my_list: list[int] = [1, 2, 3]
my_tuple: tuple[str, int, bool] = ('CLAY', 1, True)
my_set: set[int] = {1, 2, 3}
my_dict: dict[str, int] = {'age', 20}

类型注解的语法

除了使用 变量: 类型, 这种语法做注解外,也可以在注释中进行类型注解。 、

语法: # type: 类型

class Student:
    pass

import random
var_1 = random.randint(1, 10) # type: int

函数(方法)的类型注解

形参注解

语法:

def 函数方法名(形参名: 类型, 形参名: 类型, ......):
    pass

返回值注解

语法:

def 函数方法名(形参名: 类型, 形参名: 类型, ......) -> 返回值类型:
    pass

示例代码:

def add(x: int, y:int) -> int:
    return x + y

union类型

有种情况,比如dict中,我要求限制类型,key是str,但value可以是int或者str,如何做?

from typing import Union
my_dict: dict[str: Union[str, int]] = {'name': 'CLAY', 'age': 10}

Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。

from typing import Union

def func(data: Union[int, str]) -> Union[int, str]:
    pass

10.8、多态

什么是多态?

多态,指的是:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态。

同样的行为(函数),传入不同的对象,得到不同的状态。 

抽象类(接口)

十一、操作SQL

11.1、基本操作

第一步:安装pymysql

pip install pymysql

第二步:创建到MySQL的数据库链接

from pymysql import Connection

# 获取到Mysql数据库的链接对象
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='root'
)

# 打印Mysql数据库软件信息
print(conn.get_server_info())

conn.close()

第三步:执行SQL语句

from pymysql import Connection

# 获取到Mysql数据库的链接对象
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='root'
)

# 获取游标对象
cursor = conn.cursor()
# 选择test数据库
conn.select_db('test')
# 执行SQL语句
cursor.execute("create table test_pymsql(id int, info varchar(255))")

conn.close()

11.2、插入数据

from pymysql import Connection

# 获取到Mysql数据库的链接对象
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='root',
    autocommit=True # 设置事务自动提交
)

# 获取游标对象
cursor = conn.cursor()
# 选择test数据库
conn.select_db('test')
# 执行SQL语句
cursor.execute("insert into test_pymsql values(1, '随便写点什么')")

conn.close()

11.3、查询数据

from pymysql import Connection

# 获取到Mysql数据库的链接对象
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='root',
    autocommit=True # 设置事务自动提交
)

# 获取游标对象
cursor = conn.cursor()
# 选择test数据库
conn.select_db('test')
# 执行SQL语句
cursor.execute("select * from test_pymsql")
# 获取查询结果
results: tuple = cursor.fetchall()
for r in results:
    print(r)

conn.close()

十二、PySpark

咱们这里就是把它当做一个第三方库来使用,用做数据处理。

12.1基础准备

PySpark库的安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyspark

构建PySpark执行环境入口对象

from pyspark import SparkConf, SparkContext

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark_app")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

# 打印PySpark的运行版本
print(sc.version)

sc.stop()

12.2、数据输入

RDD对象

如图可见,PySpark支持多种数据的输入,在输入完成后,都会得到一个:RDD类的对象

RDD全称为:弹性分布式数据集(Resilient Distributed Datasets)

PySpark针对数据的处理,都是以RDD对象作为载体,即:

  • 数据存储在RDD内
  • 各类数据的计算方法,也都是RDD的成员方法
  • RDD的数据计算方法,返回值依旧是RDD对象

PySpark的编程模型(左图)可以归纳为:

  • 准备数据到RDD -> RDD迭代计算 -> RDD导出为list、文本文件等
  • 即:源数据 -> RDD -> 结果数据 

Python数据容器转RDD对象

PySpark支持通过SparkContext对象的parallelize成员方法,将:

  • list
  • tuple
  • set
  • dict
  • str

转换为PySpark的RDD对象。

注意:

  • 字符串会被拆分出1个个的字符,存入RDD对象
  • 字典仅有key会被存入RDD对象

from pyspark import SparkConf, SparkContext

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark_app")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

rdd1 = sc.parallelize([1, 2, 3, 4, 5])
rdd2 = sc.parallelize((1, 2, 3, 4, 5))
rdd3 = sc.parallelize("abcdefg")
rdd4 = sc.parallelize({1, 2, 3, 4, 5})
rdd5 = sc.parallelize({"key1": "value1", "key2": "value2"})

print(rdd1.collect())
print(rdd2.collect())
print(rdd3.collect())
print(rdd4.collect())
print(rdd5.collect())

sc.stop()

读取文件转RDD对象

PySpark也支持通过SparkContext入口对象,来读取文件,来构建出RDD对象。

比如在当前目录下,我们创建一个hello.txt文件。

from pyspark import SparkConf, SparkContext

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark_app")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

rdd = sc.textFile('hello.txt')

print(rdd.collect())

sc.stop()

12.3、数据计算

map方法

示例代码:将list里面元素都乘以10

from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/python/python3.9/python.exe"

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

rdd = sc.parallelize([1, 2, 3, 4, 5])

# 通过map方法将全部数据都乘以10
def func(data):
    return data * 10

rdd2 = rdd.map(func())

print(rdd2.collect()) # [10, 20, 30, 40, 50]

sc.stop()

或者用lambda实现:

rdd2 = rdd.map(lambda x: x * 10)

flatMap方法

功能:对rdd执行map操作,然后进行解除嵌套操作。

示例代码: 

from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/python/python3.9/python.exe"

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

rdd = sc.parallelize(['赵云 典韦 程普', '关羽 张辽 太史慈', '张飞 许褚 黄盖'])

# 需求:将rdd数据里面的一个个人名提取出来
rdd2 = rdd.flatMap(lambda x: x.split(" "))

print(rdd2.collect()) # ['赵云', '典韦', '程普', '关羽', '张辽', '太史慈', '张飞', '许褚', '黄盖']

sc.stop()

这是采用flatMap实现,其实也可以使用map方法,但效果却不同,如:

当我把代码改为:

# 需求:将rdd数据里面的一个个人名提取出来
rdd2 = rdd.map(lambda x: x.split(" "))

结果就变成了:

[['赵云', '典韦', '程普'], ['关羽', '张辽', '太史慈'], ['张飞', '许褚', '黄盖']]

虽然也能实现,但没有解除嵌套。

reduceByKey方法

功能:针对KV型RDD,自动按照key分组,然后根据你提供的聚合逻辑,完成组内数据(value)的聚合操作。

白话讲其实就相当于mysql的group by操作,按key进行分组,然后你可以传入逻辑,比如同组的值相加等操作。

示例代码:

from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/python/python3.9/python.exe"

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

# 需求:分别统计男生总分和女生总分
rdd = sc.parallelize([('男', 99), ('男', 88), ('女', 75), ('女', 56)])

# 需求:将rdd数据里面的一个个人名提取出来
rdd2 = rdd.reduceByKey(lambda a, b: a + b)

print(rdd2.collect()) # [('男', 187), ('女', 131)]

sc.stop()

filter方法

功能:过滤想要的数据进行保留。

示例代码:保留偶数

from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/python/python3.9/python.exe"

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

# 需求:保留偶数
rdd = sc.parallelize([1, 2, 3, 4, 5])

rdd2 = rdd.filter(lambda num: num % 2 == 0)

print(rdd2.collect()) # [2, 4]

sc.stop()

distainct方法

功能:对rdd数据进行去重操作,返回新rdd。

示例代码:

from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/python/python3.9/python.exe"

# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")

# 基于SparkConf类对象创建SparkContext类对象
sc = SparkContext(conf=conf)

# 需求:去重
rdd = sc.parallelize([1, 2, 3, 4, 5, 1, 2, 4])

rdd2 = rdd.distinct()

print(rdd2.collect()) # [1, 2, 3, 4, 5]

sc.stop()

sortBy方法

功能:对rdd数据进行排序,基于你指定的排序依据。

语法:

rdd.sortBy(func, ascending=False, numPartitions=1)
# ascending:True升序 False降序
# numPartitions:用多少分区排序

12.4、数据输出

collect方法

功能:将rdd各个分区内的数据,统一收集到Driver中,形成一个List对象。

用法:

rdd.collect()

返回值是一个list。

take方法

功能:取rdd的前N个元素,组合成list返回给你。

rdd = sc.parallelize([1, 2, 3, 4, 5])

take_list = rdd.take(3)

print(take_list) # [1, 2, 3]

count方法

功能:计算rdd有多少条数据,返回值是一个数字。

rdd = sc.parallelize([1, 2, 3, 4, 5])

count = rdd.count()

print(count) # 5

到此,Python全部更新完成,欢迎小伙伴们点赞收藏关注,感谢!!!

Python基础入门教程(上)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/814423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【雕爷学编程】MicroPython动手做(23)——掌控板之WiFi与蓝牙

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

备件管理数字化转型的基础是什么?

备件管理的数字化转型是由多种因素驱动的&#xff0c;以及优化整个流程以提高效率、降低成本和增强客户满意度的愿望。这一转变的一些关键基础包括&#xff1a; 数据驱动的洞察&#xff1a;数字化转型可以收集和分析与备件库存、使用和维护相关的大量数据。这种数据驱动的方法有…

(12)Qt事件系统(one)

目录 Qt Event System 事件处理的方法 系统事件处理函数 基本事件 窗口显示事件 窗口关闭事件 窗口隐藏事件 窗口移动事件 窗口大小改变事件 窗口状态改变事件 鼠标事件 鼠标进入、离开事件 鼠标按下抬起事件 鼠标双击事件 鼠标移动事件 鼠标滚轮事件 示例&#xff1…

【数据结构与算法】斐波那契查找(黄金分割法)

斐波那契查找&#xff08;黄金分割法&#xff09; 黄金分割点是指把一条线段分割成两部分&#xff0c;使其中一部分与全长之比等于另一部分与这部分之比。取其前三位数字的近似值是 0.618。由于按此比例设计的造型十分美丽&#xff0c;因此称为黄金分割&#xff0c;也称为中外比…

css 动画之旋转视差

序&#xff1a;网上看到的一个例子&#xff0c;做一下 效果图&#xff1a; 代码&#xff1a; <style>.content{width: 300px;height: 300px;margin: 139px auto;display: grid;grid-template-columns: repeat(3,1fr);grid-template-rows: repeat(3,1fr);grid-template:…

《水经注地图服务》发布的影像数据在MapBox中调用(仅墨卡托)

MapBox源码下载 由于MapBox的源码下载略微有点复杂&#xff0c;我们有必要在这里为大家分享一下它的下载的方法&#xff0c;如果你已经从百度网盘下载了MapBox源码&#xff0c;请略过本节。 首先打开MapBox官网&#xff0c;然后点击“Documentation\Mapbox GL js”&#xff0…

PostgreSql 锁

一、概述 在 PostgreSQL 事务中提到&#xff0c;多个用户访问相同数据时可能出现脏读&#xff0c;不可重复度&#xff0c;幻读&#xff0c;更新丢失的问题&#xff0c;为解决这些问题&#xff0c;定义了不同的隔离级别&#xff0c;而隔离级别的具体实现&#xff0c;依靠的就是数…

计算机图形学笔记2-Viewing 观测

观测主要解决的问题是如何把物体的三维“模型”变成我们在屏幕所看到的二维“图片”&#xff0c;我们在计算机看到实体模型可以分成这样几步&#xff1a; 相机变换(camera transformation)或眼变换(eye transformation)&#xff1a;想象把相机放在任意一个位置来观测物体&#…

实用上位机--QT

实用上位机–QT 通信协议如下 上位机设计界面 #------------------------------------------------- # # Project created by QtCreator 2023-07-29T21:22:32 # #-------------------------------------------------QT += core gui serialportgreaterThan(QT_MAJOR_V…

LLM - model batch generate 生成文本

一.引言 LLM model 类 generate 支持传递 num_return_sequences 进行批量生成&#xff0c;下面简单介绍下原始模型 generate 和 lora 模型 generate 的代码并给出基于 Baichuan-7B 和 ChatGLM 的批量预测效率。 二.generate 参数 介绍 batch generate 之前&#xff0c;先熟悉…

机器学习-Basic Concept

机器学习(Basic Concept) videopptblog Where does the error come from? 在前面我们讨论误差的时候&#xff0c;我们提到了Average Error On Testing Data是最重要的 A more complex model does not lead to better performance on test data Bias And Variance Bias(偏差) …

四通道本地互联网络(LIN)收发器SIT1024Q

特点&#xff1a; ➢ 兼容“LIN 2.x/ISO 17987-4:2016 (12V)/SAE J2602” 标准&#xff1b; ➢ 兼容 K 线&#xff1b; ➢ 内置过温保护功能&#xff08;热关断&#xff09;&#xff1b; ➢ 内置显性超时功能&#xff1b; ➢ 内置 30kΩ 总线上拉从机电阻&#xff1b; ➢…

微软开测“Moment4”启动包:Win11 23H2要来了

近日&#xff0c; 有用户在Win11最新的7月累积更新中发现&#xff0c;更新文件中已经开始出现了对“Moment4”的引用。 具体来说&#xff0c;在7月累积更新中&#xff0c;微软加入了“Microsoft-Windows-UpdateTargeting-ClientOS-SV2Moment4-EKB”“Microsoft-Windows-23H2Ena…

0101日志-运维-mysql

1 错误日志 错误日志&#xff08;Error Log&#xff09;&#xff1a;错误日志记录了MySQL引擎在运行过程中出现的错误和异常情况。这些错误可能包括启动和关闭问题、数据库崩溃、权限问题等。错误日志对于排查和解决MySQL引擎问题非常有帮助。 改日志默认开启&#xff0c;默认存…

python在不同坐标系中绘制曲线

文章目录 平面直角坐标系空间直角坐标系极坐标地理坐标 平面直角坐标系 回顾我们的数据可视化的学习历程&#xff0c;其实始于笛卡尔坐标系的创建&#xff0c;并由此建立了数与形的对应关系。在笛卡尔坐标系中随便点上一点&#xff0c;这个点天生具备坐标&#xff0c;从而与数…

基于LSTM神经网络的电力负荷预测(Python代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f308;3 Python代码及数据 &#x1f389;4 参考文献 &#x1f4a5;1 概述 前馈神经网络的输出只依赖当前输入&#xff0c;但是在文本、视频、语音等时序数据中&#xff0c;时序数据长度并不固定&#xff0c;前馈神经…

我对排序算法的理解

排序算法一直是一个很困惑我的问题&#xff0c;早在刚开始接触 数据结构的时候&#xff0c;这个地方就很让我不解。就是那种&#xff0c;总是感觉少了些什么的感觉。一开始&#xff0c;重新来过&#xff0c;认真来学习这一部分&#xff0c;也总是学着学着就把概念记住了。过了一…

词典项目练习

思维导图 客户端 #include "head.h" //用户提示界面 void help_info1() {printf("\t-----------------------------------------------\n");printf("\t| HENRY 在线辞典 |\n");printf("\t|版本:0.0.1 …

官方实锤!AMD真的已经有了大小核:不搞Intel那一套

Intel 12代酷睿开始引入大小核混合架构&#xff0c;多核跑分提升立竿见影&#xff0c;在游戏、渲染等场景中也有很好的辅助作用&#xff0c;但因为大核心、小核心基于完全不同的架构&#xff0c;需要复杂的系统、软件调度配合&#xff0c;也直接导致失去了AVX-512指令集。 AMD也…

解决多线程环境下单例模式同时访问生成多个实例

如何满足单例&#xff1a;1.构造方法是private、static方法、if语句判断 ①、单线程 Single类 //Single类&#xff0c;定义一个GetInstance操作&#xff0c;允许客户访问它的唯一实例。GetInstance是一个静态方法&#xff0c;主要负责创建自己的唯一实例 public class LazySi…