# all_python_study
**Repository Path**: binary-boy/all_python_study
## Basic Information
- **Project Name**: all_python_study
- **Description**: python基础以及进阶、面试。记录python学习路径以及过程、面试问题
- **Primary Language**: Python
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-07-04
- **Last Updated**: 2022-08-06
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# all_python_study
#### 介绍
python基础以及进阶、面试,用于记录python学习、面试
## 一 、类与对象
```python
class tortoise:
bodyColor = "绿色"
footNum = 4
weight = 10
hasShell = True
#会爬
def crawl(self):
print("乌龟会爬")
#会吃东西
def eat(self):
print("乌龟吃东西")
#会睡觉
def sleep(self):
print("乌龟在睡觉")
#会缩到壳里
def protect(self):
print("乌龟缩进了壳里")
```
面向对象中,常用术语包括:
- 类:可以理解是一个模板,通过它可以创建出无数个具体实例。比如,前面编写的 tortoise 表示的只是乌龟这个物种,通过它可以创建出无数个实例来代表各种不同特征的乌龟(这一过程又称为类的实例化)。
- 对象:类并不能直接使用,通过类创建出的实例(又称对象)才能使用。这有点像汽车图纸和汽车的关系,图纸本身(类)并不能为人们使用,通过图纸创建出的一辆辆车(对象)才能使用。
- 属性:类中的所有变量称为属性。例如,tortoise 这个类中,bodyColor、footNum、weight、hasShell 都是这个类拥有的属性。
- 方法:类中的所有函数通常称为方法。不过,和函数所有不同的是,类方法至少要包含一个 self 参数(后续会做详细介绍)。例如,tortoise 类中,crawl()、eat()、sleep()、protect() 都是这个类所拥有的方法,类方法无法单独使用,只能和类的对象一起使用。
在 Python 中,所有的变量其实也都是对象,包括**整形(int)、浮点型(float)、字符串(str)、列表(list)、元组(tuple)、字典(dict)和集合(set)**。以字典(dict)为例,它包含多个函数供我们使用,例如使用 keys() 获取字典中所有的键,使用 values() 获取字典中所有的值,使用 item() 获取字典中所有的键值对,等等。
### 1、Python __ init__()类构造方法
在创建类时,我们可以手动添加一个\__ __init__() __方法,该方法是一个特殊的类实例方法,称为**构造方法(或构造函数)**。
\____init__()__ 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数。也就是说,类的构造方法最少也要有一个 self 参数。
### 2、Python 类的实例化
```python
class CLanguage :
# 下面定义了2个类变量
name = "C语言中文网"
add = "http://c.biancheng.net"
def __init__(self,name,add):
#下面定义 2 个实例变量
self.name = name
self.add = add
print(name,"网址为:",add)
# 下面定义了一个say实例方法
def say(self, content):
print(content)
# 将该CLanguage对象赋给clanguage变量
clanguage = CLanguage("C语言中文网","http://c.biancheng.net")
```
在上面的程序中,由于构造方法除 self 参数外,还包含 2 个参数,**且这 2 个参数没有设置默认参数,因此在实例化类对象时,需要传入相应的 name 值和 add 值**(self 参数是特殊参数,不需要手动传值,Python 会自动传给它值)。
类变量和实例变量,简单地理解,定义在各个类方法之外(包含在类中)的变量为类变量(或者类属性),定义在类方法中的变量为实例变量(或者实例属性)
#### Python类对象的使用
定义的类只有进行实例化,也就是使用该类创建对象之后,才能得到利用。总的来说,实例化后的类对象可以执行以下操作:
- 访问或修改类对象具有的**实例变量**,甚至可以添加**新的实例变量或者删除已有的实例变量**;
- 调用类对象的方法,包括调用现有的方法,以及给类对象动态添加方法。
#### 给类对象动态添加/删除变量
Python 支持为已创建好的对象动态增加**实例变量**,方法也很简单,举个例子:
```python
# 为clanguage对象增加一个money实例变量
clanguage.money= 159.9
print(clanguage.money)
```
既然能动态添加,那么是否能动态删除呢?答案是肯定的,使用 del 语句即可实现,例如:
```python
#删除新添加的 money 实例变量
del clanguage.money
#再次尝试输出 money,此时会报错
print(clanguage.money)
```
#### 给类对象动态添加方法
Python 也允许为对象动态增加方法。以本节开头的 Clanguage 类为例,由于其内部只包含一个 say() 方法,因此该类实例化出的 clanguage 对象也只包含一个 say() 方法。但其实,我们还可以为 clanguage 对象动态添加其它方法。
需要注意的一点是,为 clanguage 对象动态增加的方法,Python 不会自动将调用者自动绑定到第一个参数(即使将第一个参数命名为 self 也没用)。例如如下代码:
```python
# 先定义一个函数
def info(self):
print("---info函数---", self)
# 使用info对clanguage的foo方法赋值(动态绑定方法)
clanguage.foo = info
# Python不会自动将调用者绑定到第一个参数,
# 因此程序需要手动将调用者绑定为第一个参数
clanguage.foo(clanguage) # ①
# 使用lambda表达式为clanguage对象的bar方法赋值(动态绑定方法)
clanguage.bar = lambda self: print('--lambda表达式--', self)
clanguage.bar(clanguage) # ②
```
上面的第 5 行和第 11 行代码分别使用函数、lambda 表达式为 clanguage 对象动态增加了方法,但对于动态增加的方法,Python 不会自动将方法调用者绑定到它们的第一个参数,因此程序必须手动为第一个参数传入参数值,如上面程序中 ① 号、② 号代码所示。
有没有不用手动给 self 传值的方法呢?通过借助 types 模块下的 MethodType 可以实现,仍以上面的 info() 函数为例:
```python
def info(self,content):
print("C语言中文网地址为:%s" % content)
# 导入MethodType
from types import MethodType
clanguage.info = MethodType(info, clanguage)
# 第一个参数已经绑定了,无需传入
clanguage.info("http://c.biancheng.net")
```
### 3、Python self用法详解
self 参数的具体作用是什么呢?打个比方,如果把类比作造房子的图纸,那么类实例化后的对象是真正可以住的房子。根据一张图纸(类),我们可以设计出成千上万的房子(类对象),每个房子长相都是类似的(都有相同的类变量和类方法),但它们都有各自的主人,那么如何对它们进行区分呢?
当然是通过 **self 参数,它就相当于每个房子的门钥匙**,可以保证每个房子的主人仅能进入自己的房子(每个类对象只能调用自己的类变量和类方法)。
**可以把 self 理解为当前类的地址**,Python 类方法中的 self 参数就相当于 **C++ 中的 this 指针**。
同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。
### 4、Python类变量和实例变量(类属性和实例属性)
1. 类体中、所有函数之外:此范围定义的变量,称为类属性或类变量;
2. 类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量;
3. 类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量。
#### 类变量(类属性)
类变量指的是在类中,但在各个类方法外定义的变量。举个例子:
```python
class CLanguage :
# 下面定义了2个类变量
name = "C语言中文网"
add = "http://c.biancheng.net"
# 下面定义了一个say实例方法
def say(self, content):
print(content)
```
上面程序中,name 和 add 就属于类变量。
类变量的特点是,所有**类的实例化对象都同时共享类变量**,也就是说,类变量在所有实例化对象中是作为公用资源存在的。类方法的调用方式有 2 种,
既可以使用类名直接调用,也可以使用类的实例化对象调用。
注意,因为类变量为所有实例化对象共有,通过类名修改类变量的值,会影响所有的实例化对象。通过类名修改类变量,会作用到所有的实例化对象
除了可以通过类名访问类变量之外,还可以动态地为类和对象添加类变量。例如,在 CLanguage 类的基础上,添加以下代码:
```python
clang = CLanguage()
CLanguage.catalog = 13
print(clang.catalog)
```
#### 实例变量(实例属性)
实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。另外,**实例变量只能通过对象名访问,无法通过类名访问。**
```python
class CLanguage :
def __init__(self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
# 下面定义了一个say实例方法
def say(self):
self.catalog = 13
```
此 CLanguage 类中,name、add 以及 catalog 都是实例变量。其中,由于 __init__() 函数在创建类对象时会自动调用,而 say() 方法需要类对象手动调用。因此,**CLanguage 类的类对象都会包含 name 和 add 实例变量,而只有调用了 say() 方法的类对象,才包含 catalog 实例变量。**
```python
clang = CLanguage()
print(clang.name)
print(clang.add)
#由于 clang 对象未调用 say() 方法,因此其没有 catalog 变量,下面这行代码会报错
#print(clang.catalog)
clang2 = CLanguage()
print(clang2.name)
print(clang2.add)
#只有调用 say(),才会拥有 catalog 实例变量
clang2.say()
print(clang2.catalog)
```
```python
clang = CLanguage()
print(clang.name)
print(clang.add)
#由于 clang 对象未调用 say() 方法,因此其没有 catalog 变量,下面这行代码会报错
#print(clang.catalog)
clang2 = CLanguage()
print(clang2.name)
print(clang2.add)
#只有调用 say(),才会拥有 catalog 实例变量
clang2.say()
print(clang2.catalog)
```
通过**类对象**可以访问**类变量**,**但无法修改类变量的值。这是因为,通过类对象修改类变量的值,不是在给“类变量赋值”,而是定义新的实例变量**
类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。
#### 局部变量
除了实例变量,类方法中还可以定义局部变量。和前者不同,局部变量直接以“变量名=值”的方式进行定义,例如:
```python
class CLanguage :
# 下面定义了一个say实例方法
def count(self,money):
sale = 0.8*money
print("优惠后的价格为:",sale)
clang = CLanguage()
clang.count(100)
```
通常情况下,定义局部变量是为了所在类方法功能的实现。需要注意的一点是,局部变量只能用于所在函数中,**函数执行完成后,局部变量也会被销毁。**
### 5、Python实例方法、静态方法和类方法详解
采用 @classmethod 修饰的方法为类方法;采用 @staticmethod 修饰的方法为静态方法;不用任何修改的方法为实例方法。
> 其中 @classmethod 和 @staticmethod 都是函数装饰器
#### [Python](http://c.biancheng.net/python/)类实例方法
在类中定义的方法默认都是实例方法
```python
class CLanguage:
#类构造方法,也属于实例方法
def __init__(self):
self.name = "C语言中文网"
self.add = "http://c.biancheng.net"
# 下面定义了一个say实例方法
def say(self):
print("正在调用 say() 实例方法")
```
实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用.
Python 也支持使用类名调用实例方法,但此方式需要手动给 self 参数传值。例如:
```python
#类名调用实例方法,需手动给 self 参数传值
clang = CLanguage()
CLanguage.say(clang)
```
#### 类方法