当前位置 : 首页 » 文章分类 :  开发  »  Python-基础

Python-基础

Python 学习笔记

Python 的练手项目有哪些值得推荐?
https://www.zhihu.com/question/29372574

《Python Cookbook》3rd Edition - 中文翻译
https://python3-cookbook.readthedocs.io/zh_CN/latest/copyright.html


__init__.py

Python package 中的 __init__.py 相当于包本身的代码,在包被 import 时会执行 __init__.py 中的代码


import

ImportError: No module named xxx

问题:
在 PyCharm 中可运行,在命令行中 python xx.py 运行报错 ImportError: No module named xxx,报错是自定义模块

原因:
在 IDE 中执行 python 程序,编译器会自动把当前项目的根目录加入到包查找路径中,可以理解为加到 PYTHONPATH 下,所以直接执行是没有问题的。
但是在 cmd 或者 terminal 控制台中直接使用 python 命令来执行程序,不会自动将当前项目加入到 PYTHONPATH 环境变量下,如果涉及到 import 其他文件夹下的变量就会报类似ImportError: No module named xxx 这样的错误。

解决:
使用 sys.append() 命令把报警包的所在文件夹路径加入到 PYTHONPATH

import 相对路径和绝对路径

https://python3-cookbook.readthedocs.io/zh-cn/latest/c10/p03_import_submodules_by_relative_names.html


命令行参数

sys.argv

可以通过 sys 包的 sys.argv 来获取命令行参数
sys.argv 是命令行参数列表。
len(sys.argv) 是命令行参数个数。
sys.argv[0] 表示脚本名。

import sys

print '参数个数为:', len(sys.argv), '个参数。'
print '参数列表:', str(sys.argv)

argparse

argparse 模块也是 Python 自带的一个命令行参数模块
使用 argparse 模块可以给定义 Python 脚本的命令行参数及简写,默认值、以及help

Python 命令行参数的3种传入方式
https://tendcode.com/article/python-shell/

python之parser.add_argument()用法——命令行选项、参数和子命令解析器
https://blog.csdn.net/qq_34243930/article/details/106517985


DocString 文档字符串

可以在函数体的第一行使用一对三个单引号 ''' 或者一对三个双引号 """ 来定义文档字符串。
你可以使用 __doc__(注意双下划线)调用函数中的文档字符串属性。

例如

#!/usr/bin/python
# -*- coding: UTF-8 -*-

def function():
        ''' say something here!
        '''
        pass

print (function.__doc__) # 调用 doc

结果
say something here!


__init__ 定义类的初始化方法

def __init__(self, max): 
    self.max = max 

def __init__(self):
    pass

__iter__ 定义类的迭代方法

使得该类的对象可以被迭代

def __iter__(self): 
    return self 

__call__ 方法

Python 中 __call__ 方法是一个特殊的方法,它使得一个对象可以像函数一样被调用。

class CallableObject:
    def __init__(self, name):
        self.name = name

    def __call__(self, greeting):
        return f"{greeting}, {self.name}!"

# 创建一个CallableObject对象
hello = CallableObject("World")

# 调用这个对象
print(hello("Hello"))  # 输出:Hello, World!

这个例子中,CallableObject 类定义了一个 __call__ 方法,所以可以像函数一样调用 CallableObject 的对象。
当调用 hello(“Hello”) 时,Python 会自动调用 hello.__call__("Hello")


可迭代对象

可迭代对象(Iteratable Object) 是能够一次返回其中一个成员的对象,如字符串、列表、元组、集合、字典等等之类的对象都属于可迭代对象
可迭代对象都有 __iter__ 方法,可通过 dir() 输出对象的全部属性、方法看到
isinstance(obj, Iterable) 判断对象是否可迭代对象:

>>> from collections import Iterable
>>> isinstance("str", Iterable)
True
>>> isinstance([1,2,3], Iterable)
True
>>> isinstance({"k": "v"}, Iterable)
True
>>> isinstance(35, Iterable)
False

迭代器

迭代器(Iterator) 是同时实现 __iter__()__next__() 方法的对象。
迭代器对象可通过 __next__() 方法或者一般的 for 循环进行遍历,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不能后退,终止迭代则会抛出 StopIteration 异常。

当迭代一个可迭代对象时,for 循环通过 iter() 方法获取要迭代的项,并使用 next() 方法返回后续的项。for 循环内部通过捕获 StopIteration 异常来判断迭代是否结束。

>>> iter="str".__iter__()  # 获取迭代器对象
>>> iter.__next__()
's'
>>> iter.__next__()
't'
>>> iter.__next__()
'r'
>>> iter.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

yield 生成器

一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

生成器使用 yield 语句而不是 return 语句返回结果, yield 语句一次返回一个结果,在每个结果中间,会暂停并保存当前所有的运行信息,以便下一次执行 next() 方法时从当前位置继续运行。

yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。


内置函数

range(n) 从0到n-1共n个整数

Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型,所以打印的时候不会打印列表。
Python3 list() 函数是对象迭代器,可以把 range() 返回的可迭代对象转为一个列表,返回的变量类型为列表。list(range(10))
Python2 range() 函数返回的是列表。

语法:

range(stop)
range(start, stop[, step])

start: 计数从 start 开始。默认是从 0 开始。例如 range(5)等价于 range(0, 5
stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是 [0, 1, 2, 3, 4] 没有5
step:步长,默认为1。例如:range(0, 5)等价于 range(0, 5, 1)

例如:

>>> print(*range(3))
0 1 2
>>> print(*range(0,3))
0 1 2
>>> print(*range(0,4,2))
0 2

dir() 返回属性、方法列表

dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
如果参数包含方法 __dir__(),该方法将被调用。如果参数不包含 __dir__(),该方法将最大限度地收集参数信息。

>>> dir("str")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

isinstance() 类型判断

isinstance(object, classinfo) 判断对象 object 是否 classinfo 类型,子类对象也是父类类型
classinfo 可以是直接或间接类名、基本类型或者由它们组成的元组

>>> isinstance(2,int)
True
>>> isinstance("str",str)
True
>>> isinstance("str",(str,int))
True

* 解包

把 容器 中元素当成一个个元素取出来,这个过程就是解包(Unpacking),可迭代对象都可以被解包。

>>> a,b,c=[1,2,3]
>>> a
1

多变量赋值

Python 中的多变量赋值本质也是解包操作:

>>> a,b="str",3
>>> a
'str'
>>> b
3

PEP 3132 * 解包

PEP 3132 允许左边变量个数小于右边,剩余参数都分配给带星号 * 的变量

>>> a,*b,c=[1,2,3,4]
>>> a
1
>>> b
[2, 3]
>>> c
4

元组可变参数(变量前加*)

def function(arg1, *args) 形参前加 * 表示用元组存储可变参数,本质也是 * 解包操作
function 匹配万第一个固定参数 arg1 后,剩余的参数一元组的形式存储在 args 中

def function(arg1, *args):
  print arg1
  print len(args)

字典可变参数(变量前加**)

def function(arg1, **arg) 形参前加 ** 表示用 字典 存储可变参数,这时调用函数的方法则需要采用 arg1=value1,arg2=value2 这样的形式。
两个星号只能作用于字典对象,称之为字典解包操作


typing 类型标注

https://docs.python.org/zh-cn/3.7/library/typing.html

typing 类型标注是 3.5 新版功能
Python 运行时并不强制标注函数和变量类型。类型标注可被用于第三方工具,比如类型检查器、集成开发环境、静态检查器等

例如,下面函数接受并返回一个字符串,greeting 函数的参数 name 预期是 str 类型,并且返回 str 类型。

def greeting(name: str) -> str:
    return 'Hello ' + name

类型别名

可以给类型定义别名

例如下面 ConnectionOptions 类型就等于 Dict[str, str] 类型,可用于简化复杂类型签名:

from typing import Dict, Tuple, Sequence

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

def broadcast_message(message: str, servers: Sequence[Server]) -> None:
    ...

# 等价于
def broadcast_message(
        message: str,
        servers: Sequence[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    ...

Any 类型

https://docs.python.org/zh-cn/3.7/library/typing.html#the-any-type

Any 是一种特殊的类型。静态类型检查器将所有类型视为与 Any 兼容,反之亦然, Any 也与所有类型相兼容。

下面 foo 函数的参数 item 可以是任何类型,可能包含一个 bar 函数

def foo(item: Any) -> int:
    # Typechecks; 'item' could be any type,
    # and that type might have a 'bar' method
    item.bar()
    ...

字符串

字符串格式化

age = 30
name = masikkk
str = "我是 %s, 我今年 %d" % (name, age)

f格式化字符串(3.6+)

f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。
f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:

name = 'Runoob'
str1 = f'Hello {name}'  # 替换变量

str2 = f'{1+2}'         # 使用表达式

多行字符串

同一个字符串字符串因为太长而需要换行的话,有以下几种方式:
1、反斜杠 \

s = 'aaa' \
    'bbb'
print(s)

实际上,Python3 正在抛弃这种容易出错的方法,而是用 () 表达式:

2、括号表达式

s = ('aaa'
     'bbb')
print(s)

注意:多行字符串在代码中是多行,只要字符串中没有 \n 打印出来还是同一行,只是为了不超出行宽

u字符串(Unicode)

u/U 表示unicode字符串
引号前小写的”u”表示这里创建的是一个 Unicode 字符串。

us = u'Hello World !'

如果你想加入一个特殊字符,可以使用 Python 的 Unicode-Escape 编码。如下例所示:

us = u'Hello\u0020World !'

被替换的 \u0020 标识表示在给定位置插入编码值为 0x0020 的 Unicode 字符(空格符)。

r字符串(非转义)

r/R 非转义的原始字符串
与普通字符相比,其他相对特殊的字符,其中可能包含转义字符,即那些,反斜杠加上对应字母,表示对应的特殊含义的,比如最常见的”\n”表示换行,”\t”表示Tab等。而如果是以r开头,那么说明后面的字符,都是普通的字符了,即如果是“\n”那么表示一个反斜杠字符,一个字母n,而不是表示换行了。
以r开头的字符,常用于正则表达式,对应着re模块。

strip() 移除首尾

strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
str.strip([chars]);
chars – 移除字符串头尾指定的字符序列。
返回移除字符串头尾指定的字符生成的新字符串。

str.strip('0') 移除str收尾的字符0
str.strip() 移除str收尾的空白(空格、换行)

split() 分割字符串

str.split(str="", num=string.count(str))
split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则分隔 num+1 个子字符串
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。默认为 -1, 即分隔所有。
返回分割后的字符串列表。

join() 串接

str.join(sequence) 将序列 sequence 中的元素以指定的字符 str 连接生成一个新的字符串

symbol = "-";
seq = ("a", "b", "c"); # 字符串序列
print symbol.join( seq ); # 结果 a-b-c

Tuple 元组

Python 的元组与列表类似,不同之处在于元组的元素不能修改也不能删除。
元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d"   #  不需要括号也可以

元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:

tup1 = (50) # 不加逗号,类型为整型
tup2 = (50,) # 加上逗号,类型为元组

访问元组中元素
可以使用下标索引来访问元组中的值

tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7 )

print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])

with as 上下文管理器

with as 是 Python 中的 上下文管理器 Context Manager,类似 java 中的 try with resource
原理:
with 所求值的对象必须有一个 __enter__() 方法,一个 __exit__() 方法。
enter() 方法会在 with 语句进入时被调用,其返回值会赋给 as 关键字后的变量;而 exit() 方法会在 with 语句块退出后自动被调用。

@contextlib.contextmanager 装饰器

@contextlib.contextmanager 是一个装饰器,由它修饰的方法会有两部分构成,中间由 yield 关键字分开。由此方法创建的上下文管理器,在代码块执行前会先执行 yield 上面的语句;在代码块执行后会再执行 yield 下面的语句。
yield 上面的语句就如同之间介绍过的 enter() 方法,而 yield 下面的语句就如同 exit() 方法。


list

list 判空

1、用 len 判断

if len(mylist):
    # list is not empty
else:
    # list is empty

2、由于一个空 list 本身等同于 False,可直接判断

if mylist:
    # list is not empty
else:
    # list is empty

dict

判断dict中是否有某个key

Python2 中使用 has_key 方法,此方法再 Python3 中已删除,不建议使用。

user_info = {'name': 'nock', 'age': 18}
user_info.has_key('job')

更推荐使用 innot in 方法,再 Python2 和 Python3 中都适用:

user_info = {'name': 'nock', 'age': 18}
if 'name' in user_info:
  print('exist')
if 'class' not in user_info:
  print('not exist')

读写文件

读文件

通常而言,读取文件有以下几种方式:
一次性读取所有内容,使用 read()readlines()
按字节读取,使用 read(size)
按行读取,使用 readline()

‘r’ 读模式
‘w’ 写模式
‘a’ 追加模式
‘b’ 二进制模式(可添加到其他模式中使用)
‘+’ 读/写模式(可添加到其他模式中使用)

推荐使用 with 语句,可自动调用 close 方法

读取全部

with open('/path/to/file', 'r') as f:
    data = f.read()
with open('data.txt', 'r') as f:
    lines = f.readlines()
    line_num = len(lines)
    print lines
    print line_num

按字节读取

with open('path/to/file', 'r') as f:
    while True:
        piece = f.read(1024)        # 每次读取 1024 个字节(即 1 KB)的内容
        if not piece:
            break
        print piece

按行读取

f = open("/Users/user/file.csv")
for line in f.readlines():
    print line
with open('data.txt', 'r') as f:
    while True:
        line = f.readline()     # 逐行读取
        if not line:
            break
        print line,             # 这里加了 ',' 是为了避免 print 自动换行

写文件

with open('/Users/ethan/data2.txt', 'w') as f:
    f.write('one\n')
    f.write('two')

如果上述文件已存在,则会清空原内容并覆盖掉;
如果上述路径是正确的(比如存在 /Users/ethan 的路径),但是文件不存在(data2.txt 不存在),则会新建一个文件,并写入上述内容;
如果上述路径是不正确的(比如将路径写成 /Users/eth ),这时会抛出 IOError;

如果我们想往已存在的文件追加内容,可以使用 ‘a’ 模式,如下:

with open('/Users/ethan/data2.txt', 'a') as f:
    f.write('three\n')
    f.write('four')

文件编码

my.py 中有中文,但是没有加编码声明,会报如下错误

python my.py
  File "my.py", line 11
SyntaxError: Non-ASCII character '\xe4' in file my.py on line 11, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

解决,my.py脚本第一行增加 # -*- coding: utf-8 -*-

PEP 263 – Defining Python Source Code Encodings
https://www.python.org/dev/peps/pep-0263/


条件表达式/三元运算符

#如果条件为真,返回真 否则返回假
condition_is_true if condition else condition_is_false

例如:

is_fat = True
state = "fat" if is_fat else "not fat"

异常处理

try:
  Normal execution block
except A:
  Exception A handle
except B:
  Exception B handle
except:
  Other exception handle
else:
  if no exception,get here
finally:
  print("finally")   

1、正常执行的程序在 try 下面的Normal execution block执行块中执行,在执行过程中如果发生了异常,则中断当前在Normal execution block中的执行跳转到对应的异常处理块中开始执行;
2、python 从第一个 except X 处开始查找,如果找到了对应的 exception 类型则进入其提供的 exception handle 中进行处理,如果没有找到则直接进无具体异常类型的 except 块处进行处理。无异常 except 块是可选项,如果没有提供,该 exception 将会被提交给 python 进行默认处理,处理方式则是终止应用程序并打印提示信息;
3、如果在 Normal execution block 执行块中执行过程中没有发生任何异常,则在执行完 Normal execution block 后会进入 else 执行块中(如果存在的话)执行。
4、无论是否发生了异常,只要提供了 finally 语句,以上 try/except/else/finally 代码块执行的最后一步总是执行 finally 所对应的代码块。

注意:
1、在上面所示的完整语句中 try/except/else/finally 所出现的顺序必须是 try -> except X -> except -> else -> finally,即所有的 except 必须在 else 和 finally 之前,else(如果有的话)必须在 finally 之前,而 exceptX 必须在 except 之前。否则会出现语法错误。
2、对于上面所展示的 try/except 完整格式而言,else 和 finally 都是可选的,而不是必须的,但是如果存在的话 else 必须在 finally 之前,finally(如果存在的话)必须在整个语句的最后位置。
3、在上面的完整语句中,else 语句的存在必须以 except X 或者 except 语句为前提,如果在没有 except 语句的 try block 中使用 else 语句会引发语法错误。也就是说 else 不能与 try/finally 配合使用。


python -V 查看python版本

python -Vpython --version

$ python -V
Python 2.7.16

python2升级python3

编译安装python3.7

很多服务器自带了 python 2

$ python -V
Python 2.7.5
$ whereis python
python: /usr/bin/python /usr/bin/python2.7 /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/share/man/man1/python.1.gz
$ ll python*
lrwxrwxrwx. 1 root root    7 1月  29 2019 python -> python2
lrwxrwxrwx. 1 root root    9 1月  29 2019 python2 -> python2.7
-rwxr-xr-x. 1 root root 7216 10月 31 2018 python2.7

安装编译 Python3 需要依赖的包

sudo yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make libffi-devel

安装 pip

#运行这个命令添加epel扩展源
yum -y install epel-release
#安装pip
yum install python-pip

下载 python 3.7
在 python 官网找到下载链接 https://www.python.org/downloadsk/
sudo wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz

解压
sudo tar -xzvf Python-3.7.0.tgz

进入 Python-3.7.0 目录,依次执行下面命令进行手动编译
sudo ./configure prefix=/usr/local/python3
如果报错 configure: error: no acceptable C compiler found in $PATH
说明没有安装合适的编译器。这时,需要安装/升级 gcc 及其它依赖包
sudo yum install gcc gcc-c++
安装完后继续执行
sudo ./configure

编译安装
sudo make && make install

1、报错 zipimport.ZipImportError: can’t decompress data; zlib not available
是因为缺少zlib 的相关工具包导致的, 安装zlib相关依赖包
sudo yum install zlib*
只安装 zlib 包后还是会报错,还需一个修改
在重新编译之前还需要在安装源文件中修改 Modules/Setup.dist 文件,将

#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz

这行前面的注释 # 去掉,保存好再次编译安装

2、报错 /usr/bin/install: 无法删除”/usr/local/bin/python3.7m”: 权限不够
感觉可能是因为我没用root账号执行,su 切换为 root 账号后再编译安装

3、报错 ModuleNotFoundError: No module named ‘_ctypes’
3.7 版本需要一个新的包libffi-devel,安装此包之后再次进行编译安装
yum install libffi-devel
终于安装成。

设置 3.7 为默认版本

安装 3.x 完成后查看版本

$ python3 -V
Python 3.7.4
$ python -V
Python 2.7.16

将原来 python 的软链接重命名(centos 7中默认已有 python2 软链,不需再手动创建)
sudo mv /usr/bin/python /usr/bin/python2
将 python3 链接到 /usr/bin/
sudo ln -s /usr/local/python3/bin/python3.7 /usr/bin/python3.7
将 python3.7 链接到默认python命令 /usr/bin/python, 强制覆盖:
sudo ln -sf /usr/bin/python3.7 /usr/bin/python
这时,再查看 Python 的版本:

$ python -V
Python 3.7.0

输出的是 3.x,说明默认已经使用的是 python3 了

配置 yum 和 yum-utils

升级 Python 之后,由于将默认的 python 指向了 python3,yum 不能正常使用(yum必须用python2),需要编辑 yum 的配置文件:
sudo vim /usr/bin/yum
#!/usr/bin/python 改为 #!/usr/bin/python2,保存退出即可。
如果装了 yum-utils 也需要将 yum-config-manager 脚本中的 python 改为 python2
sudo vim /usr/bin/yum-config-manager
#!/usr/bin/python 改为 #!/usr/bin/python2,保存退出即可。

CentOS 7 下 安装 Python3.7
https://segmentfault.com/a/1190000015628625

新装的CentOS 7安装python3
https://blog.csdn.net/lovefengruoqing/article/details/79284573

Linux 升级 Python 至 3.x
https://blog.csdn.net/liang19890820/article/details/51079633

问题解决zipimport.ZipImportError: can‘t decompress data; zlib not availabl
https://m.pythontab.com/article/1365

在CentOS上安装Python3的三种方法
https://www.centos.bz/2018/01/%E5%9C%A8centos%E4%B8%8A%E5%AE%89%E8%A3%85python3%E7%9A%84%E4%B8%89%E7%A7%8D%E6%96%B9%E6%B3%95/


pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available

安装 python3.7 后发现使用pip会出现如下报错:

$ pip install flask
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Collecting flask
  Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
  Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
  Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
  Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
  Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/flask/
  Could not fetch URL https://pypi.org/simple/flask/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/flask/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
  Could not find a version that satisfies the requirement flask (from versions: )
No matching distribution found for flask
pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping

openSSL是系统自带的,所以一定是安装了的
pip 提示找不到 ssl 模块是因为 在 ./configure 过程中,如果没有加上–with-ssl参数时,默认安装的软件涉及到ssl的功能不可用,刚好pip3过程需要ssl模块,而由于没有指定,所以该功能不可用。

cd Python-3.7.4
sudo ./configure --with-ssl
sudo make && install

上一篇 Flask

下一篇 Docker

阅读
评论
6.5k
阅读预计28分钟
创建日期 2019-08-25
修改日期 2024-12-18
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论