Windows下使用多版本Python与VSCode配置虚拟环境

LastEditTime : 2023-12-15 21:42:49

0x00 前言

随着Python项目越来越多,很容易出现Python版本或者包的混乱、污染,导致原本已完成的项目出错,致使开发效率大大降低。

比如早期项目A开发完成后,因为新项目B中的Python版本或者包的更新,导致项目A的运行出错等一系列不兼容问题,那么一个隔离的虚拟环境(虚拟环境中包含了Python解释器的一个副本,并且在该虚拟环境中安装与卸载的包都只会影响到使用该虚拟环境的项目。)将使不同的项目之间互不干扰,并且提高了开发效率。

在VSCode中可以配置多个虚拟环境来适配不同的项目需求。
谨以此文作为个人学习笔记方便以后查阅。

  • 本文所使用的环境:
    • Os: Windows_NT x64 10.0.19045
    • Python: Python3.8.2 & Python3.12.1
    • Editor: VSCode Version: 1.85.0 (user setup)
    • Terminal: PowerShell

0x01 多版本Python之"py"与"python"的区别以及pip的日常使用

1. pip

pip是Python包的管理工具。提供了对Python包的安装、查看、升级、卸载等功能。

a. 更新pip
python -m pip install --upgrade pip

注意:python命令介绍请看下文。

b. 重装pip

Python附带了一个ensurepip模块,它可以在当前Python环境中安装pip。如果pip因为一些意外情况导致出现无法运行的错误,可以直接执行以下命令重装它:

python -m ensurepip --upgrade
c. pip命令代码补全

pip除了支持 bash、zsh 和 Fish 中的命令行补全之外,还支持PowerShell,需要在PowerShell配置文件$PROFILE中添加补全代码即可:

python -m pip completion --powershell | Out-File -Encoding default -Append $PROFILE

重启PowerShell或者执行命令.$PROFILE即可生效。
但是经过测试,发现补全效果不是很好,只有默认pip可以识别补全,"python -m pip""py -m pip"这两种都无法识别 ,我们可以稍微修改一下代码,在PowerShell中输入:

notepad $PROFILE

在弹出的文本编辑窗口中按以下代码修改一下之前添加的补全代码即可:

# pip powershell completion start
if ((Test-Path Function:\TabExpansion) -and -not `
    (Test-Path Function:\_pip_completeBackup)) {
    Rename-Item Function:\TabExpansion _pip_completeBackup
}
function TabExpansion($line, $lastWord) {
    $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart()
    if ($lastBlock.StartsWith("pip ")) {
        $Env:COMP_WORDS=$lastBlock
        $Env:COMP_CWORD=$lastBlock.Split().Length - 1
        $Env:PIP_AUTO_COMPLETE=1
        (& pip).Split()
        Remove-Item Env:COMP_WORDS
        Remove-Item Env:COMP_CWORD
        Remove-Item Env:PIP_AUTO_COMPLETE
    }
    elseif ($lastBlock.StartsWith("py -m pip ")) {
        $Env:COMP_WORDS=$lastBlock
        $Env:COMP_CWORD=$lastBlock.Split().Length - 1
        $Env:PIP_AUTO_COMPLETE=1
        (& py -m pip).Split()
        Remove-Item Env:COMP_WORDS
        Remove-Item Env:COMP_CWORD
        Remove-Item Env:PIP_AUTO_COMPLETE
    }
    elseif ($lastBlock.StartsWith("python -m pip ")) {
    $Env:COMP_WORDS=$lastBlock
    $Env:COMP_CWORD=$lastBlock.Split().Length - 1
    $Env:PIP_AUTO_COMPLETE=1
    (& python -m pip).Split()
    Remove-Item Env:COMP_WORDS
    Remove-Item Env:COMP_CWORD
    Remove-Item Env:PIP_AUTO_COMPLETE
    }
    elseif (Test-Path Function:\_pip_completeBackup) {
        # Fall back on existing tab expansion
        _pip_completeBackup $line $lastWord
    }
}
# pip powershell completion end

以上代码保存之后,重启PowerShell或者执行命令.$PROFILE即可生效。再次测试除了补全速度稍微慢一点之外,完美的识别了三种pip命令的代码补全。

d. 安装软件包

以常用的requests包为例:

# 从官方镜像源中安装requests最新版本包
pip install requests

install命令默认安装最新版本的包,如果项目有版本要求,那么应该注意安装的版本,可以使用<package name>==<version>来指定单独安装的包版本:

# 从官方镜像源中安装requests2.18.1版本包
pip install requests==2.18.1

用以上方法安装指定版本的包时,如果本身已安装过了,那么此时会覆盖原先已安装的版本。
对于版本号管理有以下几种格式:

  • == 指定版本号
  • => 高于此版本号
  • <= 小于此版本号
  • < 小于此版本号
  • > 大于此版本号

还可以使用requirements.txt文件来批量安装软件包,requirements文件内容一般包含了软件包名称与软件包的版本号,它可以是自己手动写入修改,也可以是从已安装的包环境中导出的(下文有介绍):

# 根据requirements.txt文件批量安装软件包
pip install -r requirements.txt
e. 设置软件包的镜像源

install命令可以带一个-i <url>选项,此选项是包索引选项,-i选项后面可附带包所在的镜像源网址<url>;如果install命令不带-i选项,那么默认会从官方镜像源安装包,此时很有可能网速会受限下载很慢,那么-i选项就很有必要了,它可以更改指定成国内访问速度比较快的镜像源网址<url>

# 从指定镜像源网址中安装requests包
pip install -i https://pypi.mirrors.ustc.edu.cn/simple/ requests
# 从指定镜像源网址中批量安装requirements.txt中的包
pip install -i https://pypi.mirrors.ustc.edu.cn/simple/ -r requirements.txt

国内访问速度比较快的镜像源网址有:

# 阿里云
https://mirrors.aliyun.com/pypi/simple/
# 百度云
https://mirror.baidu.com/pypi/simple/
# 腾讯云
https://mirrors.cloud.tencent.com/pypi/simple/
# 华为云
https://mirrors.huaweicloud.com/repository/pypi/simple/
# 网易
https://mirrors.163.com/pypi/simple/
# 豆瓣
https://pypi.doubanio.com/simple/
# 中科大
https://pypi.mirrors.ustc.edu.cn/simple/
# 清华大学
https://pypi.tuna.tsinghua.edu.cn/simple/
f. pip配置文件

除了可以在命令行设置软件包的镜像源之外,pip还支持配置文件pin.ini,配置文件可以更改命令行选项的默认值。它们是使用标准INI样式的配置文件编写的。这样每次执行命令时都会有配置文件进行约束,大大减少了不必要的麻烦。
查找pip.ini配置文件所在位置的命令:

pip config list -v
# 多版本Python可以用py命令执行对应版本的pip
py -3.8 -m pip config list -v #python3.8版本
py -3.12 -m pip config list -v #python3.12版本

关于py命令的介绍,后文会有讲解,这里先略过,命令执行结果如下:

pip配置文件所在位置.png

上面列出的是pip试图加载配置文件的顺序,至于variant后面表示的含义,pip官网有详细的介绍:

pip has 3 “levels” of configuration files:

  • global: system-wide configuration file, shared across users.
  • user: per-user configuration file.
  • site: per-environment configuration file; i.e. per-virtualenv.

从中可以看出pip的配置文件位置有三种:系统级配置文件、用户配置文件和当前环境配置文件;另外,前面的globaluser这两类的配置文件对于多版本Python来说是可以通用的,而唯一有区别的是site级的配置文件,它位于当前版本下的安装目录中。
所以对于怎么来设置pip的配置文件pip.ini,就看个人喜好了,想一次配置多版本通用,那么设置globaluser;想在每个版本都给它设置一个,那么可以设置site

注意:上述pip config list -v命令列出的 4 个配置文件,是按由上至下的顺序逐级加载,如果有相同的参数名称, 后面加载的会覆盖前面的。

接下来是配置pip.ini,这里选用户级的配置文件:user(使用对应的选项--user)。如果不清楚文件是否存在,那么可以使用以下命令:

pip config --user set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip config --user set install.trusted-host mirrors.aliyun.com

该命令会在pip.ini文件不存在时,在文件夹:%APPDATA%\pip(在文件资源管理器的地址栏中输入回车即可跳转到该目录)下自动新建一个pip.ini文件,如果文件存在,那么会覆盖掉对应变量的值。

执行完上述命令后,想要修改的话,可以在PowerShell中输入以下命令并回车:

pip config edit --editor notepad

此时会使用记事本来打开pip.ini文件,参考以下内容修改保存即可:

[global]
# 设置默认的软件包安装源为PyPI(Python软件包索引)
index-url = https://mirrors.aliyun.com/pypi/simple/
# 额外的软件包安装源
extra-index-url = https://mirror.baidu.com/pypi/simple/
                  https://mirrors.cloud.tencent.com/pypi/simple/
                  https://mirrors.huaweicloud.com/repository/pypi/simple/
                  https://mirrors.163.com/pypi/simple/
                  https://pypi.doubanio.com/simple/
                  https://pypi.mirrors.ustc.edu.cn/simple/
                  https://pypi.tuna.tsinghua.edu.cn/simple/
# 设置socket超时时间100s(默认为15s)。
timeout = 100
# 关闭pip版本检查
disable-pip-version-check = true

[install]
# 用于指定可信任的主机,以解决一些安全警告。
trusted-host = mirrors.aliyun.com
               mirror.baidu.com
               mirrors.cloud.tencent.com
               mirrors.huaweicloud.com
               mirrors.163.com
               pypi.doubanio.com
               pypi.mirrors.ustc.edu.cn
               pypi.tuna.tsinghua.edu.cn
保存编码ANSI.png

注意:保存pip.ini文件时,需要选择编码格式为:ANSI,否则会报错:Configuration file contains invalid cp936 characters

g. 查看已安装的软件包

上面说到requirements.txt文件,该文件内容一般包含了软件包名称与软件包的版本号,它可以是自己手动写入修改,也可以是从已安装的软件包环境中导出的,所以pip支持已安装软件包查看及相关信息导出:

# 列出已安装的软件包
pip list
# 以requirements格式输出已安装包的列表
pip freeze
# 将以requirements格式输出已安装包的列表内容保存到requirements.txt文件中
pip freeze > requirements.txt

导出的requirements.txt文件具体内容以个人已安装的包为准,一般是包名称==版本号

requirements文件内容.png
h. 升级已安装的软件包

以常用的requests包为例:

# 将`requests`包升级到最新版本           
pip install -U requests
i. 卸载已安装的软件包

以常用的requests包为例:

pip uninstall requests

2. py

py 是python3.3版本以后才引入的适用于 Windows 的 Python 启动器,是一个位于C:\Windows\py.exe的程序,可帮助定位和执行不同的 Python 版本。
关于它的具体使用方法,可以在命令行中执行py -h查看。比较常用的命令有:

a. 列出(定位)当前系统下所有已安装的Python版本以及安装目录
# py -0 不带目录
py -0p
b. 启动不同版本的python.exe,可以使用py -x.y
# 启动已安装的python2.X版本
py -2
# 启动已安装的python3.8版本
py -3.8
# 启动已安装的python3.12版本
py -3.12

如果直接使用py命令,那么它将默认启动最新安装的python版本,如果想临时更改(重启PowerShell后无效)启动的Python版本,可以在PowerShell中设置PYTHON环境变量:$Env:PY_PYTHON
比如在PowerShell中输入:

$Env:PY_PYTHON = 3.8
# 此时py启动的是Python3.8版本
py
$Env:PY_PYTHON = 3.12
# 此时py启动的是Python3.12版本
py
c. 启动不同版本的pip

默认情况下使用pip命令,启动的是最新安装的Python版本下的pip,如果想操作不同版本的pip时,那么只需要在pip前面加上py -x.y -m即可,其它参数与默认情况下使用pip命令时一致,简单举几个例子:

# 列出python3.12下已安装的包
py -3.12 -m pip list

# 以requirements格式输出python3.8下的安装包列表
py -3.8 -m pip freeze

# 将以requirements格式输出python3.8下已安装包的列表内容保存到requirements.txt文件中
py -3.8 -m pip freeze > requirements.txt
# 将以requirements格式输出python3.12下已安装包的列表内容保存到requirements.txt文件中
py -3.12 -m pip freeze > requirements.txt

当然还可以先设置$Env:PY_PYTHON变量值后,直接使用py -m,具体使用哪种方法看个人喜好。

$Env:PY_PYTHON = 3.8
# 以requirements格式输出python3.8下的安装包列表
py -m pip freeze

更多使用方法请查看:pip -h

3. python

python命令不能像py命令一样直接指定启动的Python版本,因为它本身执行的其实就是Python安装目录下的python.exe文件(比如:C:\Programs\Python\Python38\python.exe),且它执行的Python版本还会受系统的环境变量Path所影响,优先执行环境变量Path的值最上面(前面)的一个版本。

从上文对py的介绍中大致可以看出,pypython功能更强大,不仅可以启动任意安装的Python版本,而且对pip命令也可以指定版本来启动,所以日常使用中更推荐使用py

0x02 在VSCode中切换Python解释器版本

本文使用的VSCode版本是V1.85.0 (user setup)
a. 当编辑.py文件时,在底部命令栏的右下角可以直接点击切换当前Python文件使用的解释器版本

切换Python版本1.png

b. 也可以使用快捷键Ctrl+Shift+p调出命令面板,面板中输入Python:Select Interpreter按回车。

以上两个方法均可调出一个Python解释器选项:

Python解释器版本选项.png

点击想要的Python解释器版本即可。选完之后,右下角会显示当前生效的Python解释器版本。

切换Python版本2.png

此时快捷键F5运行的即为当前选择的Python解释器版本。

0x03 在VSCode中配置Python虚拟环境

1. 使用PowerShell手动创建Python虚拟环境

Python虚拟环境的创建有四种方式,分别是:pipenv、venv、cirtualenv、conda

个人比较习惯使用venv来创建虚拟环境,其它的有兴趣可以自行查找资料。

venv 模块支持创建轻量的“虚拟环境”,每个虚拟环境将拥有它们自己独立的安装在其 site-packages 目录中的 Python 软件包集合。

以下命令行的操作均在PowerShell中进行。

a. 创建虚拟环境

创建虚拟环境前需要考虑虚拟环境存放位置,一般新建一个文件夹即可(当然不新建也可以,因为创建虚拟环境时,同时也会生成一个以虚拟环境名称命名的文件夹,具体操作看个人喜好。),例如:D:\PythonVenv,然后进入该文件夹进行虚拟环境的创建:

# 进入PythonVenv文件夹中
cd D:\PythonVenv
# 创建python3.8版本的虚拟环境py38
py -3.8 -m venv py38

这里py38是虚拟环境的名称,可以自己任意命名,另外创建完成后会生成一个py38文件夹,里面包含了python3.8版本的解释器“副本”,并把python3.8版本的标准包复制了一份。

py38.png

注意:这里使用了py命令指定Python版本来创建虚拟环境,如果用python命令(即python -m venv py38)则需要注意当前Python的版本,所以一般能用py还是尽量用py,这样在多版本Python下创建虚拟环境更清晰明了。

b. 激活虚拟环境

使用venv创建完虚拟环境py38之后,虚拟环境必须激活才能使用,激活方式是在py38\Scripts文件夹下,运行.\activate或者.\Activate.ps1命令即可,退出时则使用deactivate命令,注意这里deactivate.\activate不同,不能加文件路径.\

Scripts目录.png
# 进入Scripts文件夹
cd .\py38\Scripts
# 激活虚拟环境
# 也可用 .\Activate.ps1
.\activate
# 退出虚拟环境
deactivate

虚拟环境激活后,在命令提示符前会(py38)表示当前进入虚拟环境中,此时不管是py还是python默认使用的都是Python3.8版本(因为创建时已指定py -3.8)。

激活虚拟环境.png

c. 激活出错

如果激活时出现错误,那么应该就是当前PowerShell的执行策略不允许执行激活脚本:

激活出错.png

首先查看影响当前会话的所有执行策略,并按优先级顺序显示它们,可以执行命令:

Get-ExecutionPolicy -List
查看执行策略设置.png

这里主要关心 CurrentUser,因为当前用户的执行策略优先于本地计算机设置的执行策略。可以看到它是Restricted

Restricted

  • Windows 客户端计算机的默认执行策略。
  • 允许单个命令,但不允许脚本。
  • 阻止运行所有脚本文件,包括格式和配置文件 (.ps1xml)、模块脚本文件 (.psm1) 和 PowerShell 配置文件 (.ps1)。

此时如果想更改此执行策略,则可用以下命令来更改执行策略:

Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

执行命令后,按提示输入y,回车即可。运行效果如下图所示:

更改执行策略.png

可以看到当前执行策略已被更改成:RemoteSigned

RemoteSigned

  • Windows 服务器计算机的默认执行策略。
  • 脚本可以运行。
  • 需要受信任的发布者对从 Internet 下载的脚本和配置文件(包括电子邮件和即时消息程序)的数字签名。
  • 在本地计算机上编写且不是从 Internet 下载的脚本不需要数字签名。
  • 如果脚本已解除阻止(例如通过使用 Unblock-File cmdlet),则运行从 Internet 下载且未签名的脚本。
  • 存在运行来自 Internet 以外来源的未签名脚本以及可能存在恶意的签名脚本的风险。

此时重新执行激活脚本即可。

注意:Set-ExecutionPolicy 命令更改执行策略立即生效。 无需重启 PowerShell。如果为 LocalMachine(需要“以管理员身份运行”选项启动 PowerShell) 或 CurrentUser 作用域设置执行策略,则更改将保存在注册表中并保持有效,直到再次更改为止。

d. 在虚拟环境中安装软件包

激活虚拟环境后,安装软件包的操作跟真实环境一样,且这时在虚拟环境中已经不需要在考虑版本问题,直接使用pythonpip命令操作即可,例如:

# 列出已安装软件包
pip freeze
# 安装requests包
pip install requests
# 列出已安装软件包
pip freeze

执行效果如下:

pip安装库.png

requests包被安装在py38\Lib\site-packages文件夹中。另外可以看出虚拟环境非常干净,与真实的Python3.8版本完全隔开,另外,WARNING提示当前可以更新pip的版本,执行以下命令更新pip

# 更新pip版本
python -m pip install --upgrade pip

注意:如果pip命令不存在,则可以使用命令:python -m pip install --upgrade pip,重新安装 pip。

e. 虚拟环境中设置配置文件

前文已经介绍了pip有3个级别的配置文件,在虚拟环境中也是适用的:

pip config list -v
虚拟环境pip配置文件位置.png

可以看出虚拟环境中的pip依然可以加载真实环境中globaluser这两个级别的配置文件,如果想要彻底隔离开配置文件,那么可以参考前文的设置步骤,设置一个site级别的配置文件即可。

2. 使用VSCode创建Python虚拟环境

首先安装完Python之后,还需要在VSCode中安装Python的插件


vscode python插件.png

准备工作做完之后选择一个存放Python虚拟环境的文件夹,这里需要注意:如果是在项目文件夹下打开VSCode,那么用它创建的虚拟环境会保存在当前项目文件夹中。所以虚拟环境的存放位置需要自己考虑清楚。

这里依然拿D:\PythonVenv举例,直接鼠标右键它并选择 通过 Code 打开

pythonvenv.png

这里显示的py38是之前手动创建的虚拟环境,不用管它。按快捷键Ctrl+Shift+p打开命令面板,输入Python:Create Environment回车

vscode create Env.png

选择Venv

Venv.png

选择一个Python解释器版本,例如:Python 3.8.2 64-bit

选择Python解释器版本.png

等待创建完成即可:

creating venv.png

创建完成后,左边多了一个.venv文件夹,同时也是虚拟环境的名称,文件夹里面的文件和手动创建的虚拟环境py38是一样的,只是虚拟环境名称不一样。

.venv.png

3. 在VSCode中切换Python虚拟环境

切换之前需要做一些配置,这样打开项目的时候才可以自动识别所有虚拟环境。
在VSCode的settings.json文件中,添加以下设置:

    // 进入PowerShell时自动激活虚拟环境
    "python.terminal.activateEnvironment": true,
    // 虚拟环境存放路径
    "python.venvPath": "D:\\PythonVenv",

重启VSCode之后,随便打开一个.py文件,在编辑器底部命令栏的右下角直接点击切换即可

切换Python版本1.png

可以看到,两个虚拟环境都正确识别了

Python虚拟环境选项.png

点击选择py38虚拟环境后,右下角会显示当前生效的虚拟环境,然后按快捷键 " Ctrl+Shift+` " 打开终端,我这里设置成PowerShell了

虚拟环境切换成功.png
activate environment.png

打开终端后稍微等待一会儿,右下角会自动弹窗提示虚拟环境激活成功,这时在终端中可以随意使用虚拟环境了。

4. 总结

手动创建虽然比VSCode创建麻烦一些,但是相比来说更自由,名字、存放路径可以自由选择,VSCode创建的虚拟环境只能默认命名:.venv,且如果在同一目录下,只能创建一个.venv虚拟环境

venv existing.png

当然如果是一个项目中创建一个虚拟环境这样问题到不大,如果想像手动创建那样,都存放在一个目录下,那样就得在新建一层目录,比如:D:\PythonVenv\dir1\.venvD:\PythonVenv\dir2\.venvD:\PythonVenv\dir3\.venv... 这样会有一个问题,VSCode的"python.venvPath": "D:\\PythonVenv"设置说明:

Virtual environments located in the folder identified by the python.venvPath setting (see General Python settings), which can contain multiple virtual environments. The extension looks for virtual environments in the first-level subfolders of venvPath.

所以当它还有一层dir1dir2dir3... 文件夹时无法自动识别到虚拟环境,并且它只能配置一个文件夹,类似"python.venvPath": "D:\\PythonVenv, D:\\PythonVenv\dir1"这样设置多文件夹是无法使用的。这么一来想使用其它虚拟环境,那就只能手动选择该环境的目录了:

enter interpreter path.png

因此,我个人更喜欢手动创建虚拟环境,这样存放路径统一,使用更方便,也更好管理。

【参考资料】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容