Python basics (part 2)

The main content of this article: exception handling, functions, modules and packages .

Before starting the main story, let's take a look at the topic left by the previous Coke.

topic:

Variable a= {"name": "Coke", "age": 18, "hello": "python"}, now you need to put all the keys of a into the b list, and all the values ​​into the c list.

There are many ways to implement it, and Coke uses two ways to implement it here:

Code implementation 1:

a = {
    
    "name": "可乐", "age": 18, "hello": "python"}
b = []
c = []
for key, value in a.items():
    b.append(key)
    c.append(value)
print(f"存储key的b列表是{b}")
print(f"存储value的c列表是{c}")

Code implementation 2:

a = {
    
    "name": "可乐", "age": 18, "hello": "python"}
b = [key for key in a.keys()]
c = [value for value in a.values()]
print(f"存储key的b列表是{b}")
print(f"存储value的c列表是{c}")

Note: The second type is list comprehension. It was not mentioned in the previous article for Coke. You can chat with Coke on Baidu or privately.

Next is our main character exception handling, functions, modules and packages .

One, exception handling

What is an exception ? It is our famous "bug" brother in the IT industry. Bugs refer to some error situations when the program does not run as we expect. For example, a division expression a / b, if we do not deal with it, then there will be a / 0 situation, then the program will be abnormal. Then this is a bug.

What is exception handling ? As the name implies, when the program has exceptions, we deal with these exceptions. The default processing method in python is that after an exception occurs, the program will terminate where the exception occurs, but this may not be what we want. So we can customize the processing method through several built-in keywords.

Let's first understand two python exception handling classes:
-BaseException
-Exception

1.1 BaseException

This exception handling class is the base class for all python exception handling. We can inherit this class when we customize exception handling. (Officially not recommended)

1.2 Exception

This exception handling class is the base class for conventional processing, but Exception also inherits from BaseException. It is officially recommended that we inherit from Exception when we customize the exception class. (Official document)

1.3 Exception handling keywords

Keywords:

try except else finally raise

Syntax-try, except, else, finally:

try:
 code that may be abnormal
except Error... as e:
 code to be processed when Error occurs
else: code to
 be executed if no exception occurs
finally: code to
 be executed regardless of whether an exception occurs
Note: generally only try / except is required , Try cannot be used alone.

Example 1:

try:
    a = 1 / 0
except Exception as e:
    print(f"异常是{e}")
输出: 异常是division by zero

Example 2:

try:
    a = 1 / 0
except Exception as e:
    print(f"异常是{e}")
else:
    print("没有异常执行")
finally:
    print("执行了finally")
输出: 异常是division by zero(执行了finally

Syntax-raise:

Raise exception class (description information)
Note: raise is used to actively raise an exception.

Example:

try:
    a = 2
    raise ValueError("a不能等于2")
except Exception as e:
    print(f"异常是{e}")
输出 异常是a不能等于2

Coke- like will be explained in detail in the next Python Advanced Object Orientation.

Second, the function

2.1 Syntax

def func_name (parameter):
 code part
 return Return value
Note: The function can have a return value or no return value.

Let's take a look at a simple example first: calculate the sum of 1 + 2 +… + 9 in a function and return it .

2.1.1 No parameters, no return value

Example:

def num_sum():
    sum = 0
    for i in range(10):
        sum += i
    print(sum)

After the function is written, how do we call it?

grammar:

func_name (parameter)

Example of calling function:

num_sum()
输出 45

2.1.2 No parameters, return value

Example:

def num_sum():
    sum = 0
    for i in range(10):
        sum += i
    return sum

Let's print the value returned by the function again:

def num_sum():
    sum = 0
    for i in range(10):
        sum += i
    return sum
print(num_sum)
输出 45

2.1.3 有参数,无返回值

示例:

def num_sum(number):
    sum = 0
    for i in range(number):
        sum += i
    print(sum)

在上述函数中我们可以实现1到任何数之间所相加的和,只需要把期望的值传递给函数即可。

2.1.4 有参数,有返回值

示例:

def num_sum(number):
    sum = 0
    for i in range(number):
        sum += i
    return sum
total = num_sum(10)
print(total)

在这里我们用一个变量 total 来接收函数 num_sum 的返回值。

在函数这里有下面一些重点需要注意(每一个注意点可乐都会有一个示例)。

2.2 注意点

2.2.1 全局变量和局部变量

全局变量:在函数外部定义的变量。
局部变量:在函数内部定义的变量。
- 如果局部变量定义的名字和全局变量定义的名字相同,那么在函数体内局部变量会覆盖全局变量。
- 函数体内变量的作用域或者说生命周期,仅在函数体内有。

示例:

def scope():
    name = "可乐"
    print(f"我是函数体内的{name}")
scope()
print(f"我是函数体外的{name}")

结果如下图:

我们在函数体内定义的 name 变量是可以正常打印的,但是在函数体外抛出了 name 没有被定义。

2.2.2 修改全局变量

- 如果是不可变类型,需要通过 global 来声明操作全局变量;
- 如果是可变类型,那么可以直接操作全局变量不需要通过 global 来声明。

示例:

a = [1, 2, 3]
b = "可乐"
def scope():
    a.append(4)
    print(f"函数体内a的值是{a}")
    global b
    b = "可乐很帅"
    print(f"函数体内b的值是{b}")
scope()
print(f"全局变量a的值是{a}")
print(f"全局变量b的值是{b}")

结果如下图:

在函数传参时,实际情况下无论是可变类型还是不可变类型,传递的都是引用。但是由于不可变类型改变值后是用新的内存地址来存储,所以网上有很多这样一个结论:函数接收参数时,如果参数是可变类型,那么传递的是参数的引用;如果参数是不可变类型,那么传递的是参数的值。

所以结论是:在 python 函数传参,无论是可变类型还是不可变类型本质上都是引用传递,但是由于不可变类型不能直接修改原有的值,所以在表现上不可变类型是传值。

示例:

a = 10
b = ["可乐"]
def scope(change):
    print(f"改变前s_change的内存地址是{id(change)}")
    change = 20
    print(f"改变后s_change的内存地址是{id(change)}")
    print(f"改变后s_change的值是{change}")
def scope2(change):
    print(f"改变前s2_change的内存地址是{id(change)}")
    change.append("很帅")
    print(f"改变后s2_change的内存地址是{id(change)}")
    print(f"改变后s2_change的值是{change}")
scope(a)
print(f"a的值是{a},a的内存地址是{id(a)}")
scope2(b)
print(f"b的值是{b},b的内存地址是{id(b)}")

结果如下图:

2.2.3 函数的不定长参数和关键字参数

不定长参数:*args
关键字参数:**kwargs
在正常情况下,参数接收几个参数我们就写几个参数名就可以了,可是在实际开发中有的函数的参数并不是固定的,那么我们就可以用关键字参数和可变参数来替代。

2.2.3.1 不定长参数

示例:

def scope(*args):
    print(args)
scope(1, 2, 3)
输出: (1,2,3)

在这里的时候需要注意,如果我们在调用函数的时候传递的是一个元组,而不是 1,2,3 这三个参数,那么这个元组就是一个参数,如果需要达到上述函数的效果,需要对他解包

示例:

a = (1, 2, 3)
def scope(*args):
    print(args)
scope(a)
scope(*a)

结果如下图:

重申:如果我们在传递函数参数时是一个元组、列表、字典等时,如果不对他解包,那么传递的是该元组、列表、字典的整体。如果需要对他的每个元素进行分别传参,则需要对其解包。

2.2.3.2 关键字参数

关键字参数是针对字典这键值对类型的。

示例:

a = {
    
    "name": "可乐", "age": 18}
def scope(**kwargs):
    print(kwargs)
scope(name="可乐", age=18)
scope(**a)

注意:函数参数的匹配顺序(指定参数名除外)为从左往右

示例:

def scope(name1, name2, name3):
    print(name1)
    print(name2)
    print(name3)
scope("可乐", "python", "是可乐呀")
print()
scope(name3="可乐", name2="是可乐呀", name1="python")

结果如下图:

注意:如果在函数的参数既有不定长参数和关键字参数又有普通参数,那么一定要将普通参数放在最前面。

2.2.4 默认参数

顾名思义:默认参数就是如果我们没有传值给这个参数的话,那他就是默认值。

示例1:

def scope(name="可乐"):
    print(name)
scope()
输出: 可乐

示例2:

def scope(name="可乐"):
    print(name)
scope("是可乐呀")
输出: 是可乐呀

2.2.5 匿名参数

解释:匿名函数也就是这个函数是没有名字的,不过匿名函数的关键字不是通过def来定义,而是 lambda

语法:

lambda 参数(可以多个) : 表达式(只能有一个)
注:返回一个新的函数

示例:

b = lambda x, y: y + x
print(b(1, 2))
输出: 3

解读:① 定义一个匿名函数用来计算 x+y 的值并且返回。② 匿名函数定义完后返回新的函数给变量 b,b 调用这个匿名函数并且将参数 1,2 传递。③ 打印 x+y 表达式的值。

函数更高层次的理解和使用例如:装饰器,闭包。可乐会在高级部分讲解。

三、模块和包

模块:我们可以通俗的理解模块就是一个 py 文件包(若干个 py 文件 + ini.py 组成的文件夹就是一个包)。

init.py 文件的作用:用于初始化这个包。

如下图:

如果我们有一个函数或者变量需要从另外的一个包当中引用过来,那么我们应该怎么做呢?答案就是导包

3.1 导包

语法:

① import module_name
② from xxx import module_name
③ from module_name import *

示例如下图:


输出:hello world
其他的两种方式大家可自己线下测试。

3.2 模块的搜索路径顺序

当前主目录 > PTYHONPATH 目录(开始安装 python 时设置的环境变量路径,忘记可往回看 python 安装) > 标准的连接库路径 > .pth 文件 > 第三方包(site-package 目录)

我们也可以通过 sys.path 来查看搜索路径。

如下图:

注意:我们根据模块的搜索路径顺序得知,我们在给包或者模块取名的时候,一定不要和系统包或者第三方包同名,否则会找不到对应的方法。

3.3 相对路径和绝对路径

相对路径:相对于你的工作目录的路径
绝对路径:以系统的根路径为为根目录,如:windows C: linux /

到此Python基础篇的内容就全部结束了,大家在学习过程中遇到疑问可以私聊可乐,可乐看到了都会一一回复的( •̀ ω •́ )✧。


< END>

在这里插入图片描述

Guess you like

Origin blog.csdn.net/weixin_38607483/article/details/112474639