# Python基础入门

此开源图书由[ithaiq](https://github.com/ithaiq)原创，创作不易转载请注明出处

<figure><img src="https://3211622456-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9MsXZAk3jHwadogpgvKW%2Fuploads%2FopB03NtP9Qsn5bMh5SAn%2Fimage.png?alt=media&#x26;token=b8296ff4-cbff-41ae-a96c-19dcfd87af64" alt=""><figcaption><p>Python基础思维导图</p></figcaption></figure>

## 数据类型

Python 的数据类型有 int(整数)、float(浮点数)、字符串、布尔值、None、列表、元组、字典、集合等

## 输入和格式化

```python
name = input('请输入姓名：')
age = input('请输入年龄')
print('你叫'+name+'，今年' + age + '岁了')
print('你叫{}，今年{}岁了'.format(name,age))
```

## 循环控制

```python
namelist = ['Sophia','Emma']
#点名册
for i in namelist:
    print(i)
#打印 0 到 9 的数
for a in range(10):
    print(a)
##打印 1 到 10 的数
for a in range(1,11):
    print(a)
```

## 数据容器

```python
#列表 增删改查
a = [] | a = list()
a.append(xx)
a.remove(xx) del a[0]
a[i] = xx
a[0] | xx in a | xx not in a

#元组 增删改查
a = (1,) | a = tuple()
xx in a | xx not in a

#字典 增删改查
a = {} | a = dict()
a[key] = val
del a[key]
a.__contains__(key)| a.get(key,default)
for item in a.items() | for key,value in a.items() | for key in a.keys() | for val in a.values()

#集合 增删改查
a = set()
a.add(xx)
a.remove(xx)
xx in a | xx not in a
```

## 函数

```python
#Python 常用参数有四种：位置参数、默认参数、可变参数和关键字参数。

def f(a, data=[]):
    data.append(a)
    print(data)
#上面有问题：默认参数在Python中只会在函数定义时进行计算和分配，而不是在每次函数调用时重新计算和分配
#改写后：可以避免默认参数在多次调用中被共享的问题
def f(a, data=None):
    if data == None:
        data = []
    data.append(a)
    print(data)

def connect(ipaddress, *ports, **kw):
	for port in ports:
		print("Port: ", port)
	for key,value in kw.items():
		print(f'{key}: {value}')

ipaddress = '192.168.1.1'
params = (25, 26, 27)
prop = {'device': 'eth0', 'proto': 'static'}
connect(ipaddress, *params, **prop)

#限制必须使用关键字参数
def hello(*, name,test):
	print(name)

#全局变量和本地变量
a = 9
def change():
    global a
    print(a)
    a = 100
change()
```

## 模块和包

* 对于 Python 来说，一个 Python 文件就是一个模块，一个目录就是一个包；
* 在 Python3.3 之前的版本中，一个目录必须要有 **init**.py 文件才能被视为 Python 包，之后的版本不再需要这个文件来标记了；
*   pip 命令

    ```bash
    pip install xxx
    pip install -U xxx
    pip show xxx
    pip uninstall xxx
    pip freeze | grep -i xxx
    ```

## 异常处理

```python
try:
    有可能抛出异常的代码
except 异常类型名称：
    处理代码
except 异常类型名称：
    处理代码
finally
    不论是否捕获了异常，这里的代码都会执行
    
import math

r = input('输入圆的半径：')

def area(r):
    try:
        area = int(r) ** 2 * math.pi
    except ValueError:
        # 打印此信息
        print('请输入整数数值作为半径')
        exit()
    if int(r) > 11:
        raise ImportError('半径数值太大')
    print('圆的面积等于 {:.2f}'.format(area))

if __name__ == '__main__':
    try:
        area(r)
    except ImportError as e:
        print(e)
        exit()
```

## 文件管理

*   open参数

    * `"r"`，以只读模式打开，你只能读取文件，不能编辑/删除文件的任何内容
    * `"w"`，以写入模式打开，如果文件不存在，则新建一个；如果文件存在，写入的数据将会覆盖文件里面原有的所有内容
    * `"a"`，以追加模式打开，写入到文件中的任何数据将自动添加到末尾
    * `"b"`，以二进制的方式读写

    ```python
    with open('test.txt') as f1, open('test2.txt', 'w') as f2:
      f2.write(f1.read())
    ```



*   json

    ```python
    import json

    courses = {1: 'Linux', 2: 'Git', 3: 'Vim'}

    json.dumps(courses)

    with open('test.json','w') as f:
        json.dump(courses,f)

    with open('test.json') as f:
        d1 = json.load(f)
    ```

## 面向对象

### 私有属性

* 命名：在实际使用中，如果你想要将一个变量作为“内部使用”，可以使用单下划线 `_`；如果你想要将一个变量真正地作为私有变量，只在类的内部使用，可以使用双下划线 `__`（不能被子类继承）

### 继承和多态

```python
class Animal:
    type_ = 'animal'
    
    @classmethod
    def get_type(cls):
        return cls.type_
    
    @staticmethod
    def test():
        print('test')
        
    def __init__(self, name):
        self._name = name

    def get_name(self):
        return self._name

    def set_name(self, value):
        self._name = value
    def say(self):
        print(self._name + 'is saying something')

class Dog(Animal):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age
    def say(self):
        print(self._name + 'is making sound wang wang wang...')


class Cat(Animal):
    def say(self):
        print(self._name + 'is making sound miu miu miu...')
        
dog = Dog('Tom')
dog.get_name()
dog.say()
```

## 常用内置模块

*   os 、sys 、datatime、copy、collections

    ```python
    import os,sys,copy
    from datetime import date, datetime
    from collections import Iterable,Iterator,Generator,OrderedDict,Counter,namedtuple

    os.path.abspath(filename)   # 返回文件的绝对路径
    os.path.basename(filename)  # 返回文件名
    os.path.dirname(filename)   # 返回文件目录
    os.path.isfile(filename)    # 判断路径是否为文件
    os.path.isdir(filename)     # 判断路径是否为目录
    os.path.exists(filename)    # 判断路径是否存在
    os.path.join
    os.path.split
    os.mkdir
    os.remove

    sys.argv

    datetime.now()
    time.time()

    copy.copy()
    copy.deepcopy()

    #OrderedDict 有序字典  Python 3.7后标准字典也是有序的
    #Counter 用来统计一个可迭代对象中各个元素出现的次数
    #namedtuple 能够用来创建类似于元组的类型，可以用索引来访问数据，能够迭代，也可以通过属性名访问数据

    ```

## 高阶函数

### 装饰器 Decorator

```python
from datetime import datetime
from functools import wraps

def print_datetime(func):
    @wraps(func)
    def wrapper(*args, **kw):
        print(datetime.now())
        func(*args, **kw)
    return wrapper

@print_datetime
def hello(name):
    print(f'i\'m {name}')

hello('test')


class User:
    def __init__(self, name, email, password):
        self.name = name
        self.email = email
        self._password = password

    @property
    def password(self):
        return self._password

    @password.setter
    def password(self, password):
        self._password = password
```

### 迭代器Iterator、生成器Generator

* 一个长列表会占用大量内存，而迭代器不会，每个元素都是迭代器一步步算出来的，迭代器内的元素不是本来就在内存中。此外，迭代器会进化成生成器，生成器进化成协程，协程可以实现高性能异步 I/O 程序，未来可能会帮助 Python 脱掉 “运行速度不行” 的帽子的 Asyncio 库
*   使用 Python 内置方法 iter 将可迭代对象变成迭代器，所有的迭代器其实都实现了 `__iter__` 和 `__next__` 这两个特殊方法，next 方法实际上调用的是迭代器的 **next** 方法

    ```python
    color_list = ['rea', 'green', 'powderblue', 'white']
    for color in color_list:
        print(color)

    for color in color_list:
        print(color)

    from collections.abc import Iterable,Iterator

    print(isinstance(color_list, Iterable))
    print(isinstance(color_list, Iterator))

    color_iter = iter(color_list)

    print(isinstance(color_iter, Iterator))

    for color in color_iter:
        print(color)
    for color in color_iter:
        print(color) #没有了
    ```
* 生成器一定是迭代器，迭代器一定是可迭代对象，，**使用小括号，这是它与列表解析的唯一区别**；生成器有一些特殊方法是迭代器不具有的
*   `return` 可以返回有效的 Python 对象，而 `yield` 返回的是一个生成器，函数碰到 `return` 就直接返回了，而使用了 `yield` 的函数，到 `yield` 返回一个元素，当再次迭代生成器时，会从 `yield` 后面继续执行，直到遇到下一个 `yield` 或者函数结束退出。

    ```python
    def fib(n):
        current = 0
        a = b = 1
        while current < n:
            yield a
            a,b=b,a+b
            current+=1

    from collections.abc import Generator
    f5 = fib(5)
    isinstance(f5,Generator)
    for x in f5:
        print(x)
    ```

### 匿名函数Lambda

*   列表解析

    ```python
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    new_nmbers  = []
    for x in numbers:
        if x % 2 == 0:
            new_nmbers.append(x)
    new_nmbers
    new_nmbers = [ x for x in numbers if x % 2 == 0]
    #可以用list(filter(lambda x: x % 2 == 0, numbers))但是推荐列表解析
    ```
*   字典解析

    ```python
    d = {'a': 1, 'b': 2, 'c': 3}

    {k:v*v for k, v in d.items()}
    {k:v*v if k == 'b' else v for k, v in d.items() }
    ```
*   元组拆包

    ```python
    t = ('hello', 'test')
    a, b = t

    a, *b, c = range(1, 11)
    ```

### Sorted、filter、map、reduce

```python
from functools import reduce

b = [9, 'Python', True, 3.14, 2019, -4, abs]
def func1(i):
    if isinstance(i,int):
        return True
    else:
        return False
def func2(i):
    return i**2

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

reduce(func3,list(map(func2,list(filter(func1,b)))))
#改成lambda
reduce(lambda x,y: x + y,list(map(lambda i: i**2,list(filter(lambda i: True if isinstance(i,int) else False,b)))))
```
