探索 Python 的 Typing 库:增强代码健壮性

Python 的 typing 库自 Python 3.5 引入,为动态类型的 Python 带来了静态类型注解功能,使开发者能够编写更健壮、可维护的代码。本文将深入探讨 typing 模块的主要功能、优势以及实用示例。

为什么使用类型注解?

类型注解通过明确声明变量、函数参数和返回值的预期类型,提升了代码的可读性、可维护性和可靠性。它们支持像 mypy 这样的静态类型检查工具,在运行前捕获潜在错误。此外,类型注解还能增强 IDE 对自动补全和重构的支持,提高开发效率。

开始使用 Typing 库

typing 模块提供了丰富的工具来定义类型注解。以下是一些常用功能的介绍。

基本类型注解

类型注解可用于变量、函数参数和返回值,语法简单直观。

from typing import List, Dict

# 变量注解
name: str = "Alice"
age: int = 30

# 带类型注解的函数
def greet(person: str) -> str:
    return f"你好,{person}!"

在此例中,name 声明为 str 类型,ageint 类型,greet 函数接受一个 str 参数并返回一个 str。使用 mypy 等静态类型检查工具可以确保类型使用正确。

集合类型的复杂注解

typing 模块支持对列表、字典和元组等集合类型的复杂注解。

from typing import List, Dict, Tuple

# 整数列表
numbers: List[int] = [1, 2, 3, 4]

# 字符串键和浮点值字典
scores: Dict[str, float] = {"Alice": 95.5, "Bob": 87.0}

# 指定类型的元组
point: Tuple[int, int, str] = (10, 20, "原点")

这些注解清楚地表明了集合内元素的预期类型,减少歧义和潜在错误。

📅 2025-09-29
在 Windows 下使用 Python virtualenv的教程
在 Python 开发中,使用虚拟环境是一种常见的最佳实践。它可以帮助我们在同一台计算机上管理多个具有不同依赖关系的项目,避免依赖冲突和版本混乱。本文将介绍如何在 Windows 系统下使用 Python 的 virtualenv 工具创建和管理虚拟环境,并提供一些实用的技巧和建议。
📅 2024-06-07
Python venv:创建虚拟环境及生成 requirements.txt
在 Python 开发中,管理项目的依赖是一项重要的任务。为了避免不同项目之间的依赖冲突,我们通常会使用虚拟环境来隔离每个项目的依赖。Python 的 venv 模块就是一个用于创建虚拟环境的工具。在本文中,我们将介绍如何在 Windows 环境下使用 venv 模块创建虚拟环境,并生成 requirements.txt 文件来管理项目的依赖。
📅 2024-05-19

在使用 Python 进行开发时,我们经常会用到 pip 来安装各种包。但有时默认的源下载速度可能较慢,这时候配置国内的镜像源就很有必要了。这里介绍如何在 Windows 系统中配置 pip 的清华源。

第一步:创建配置文件

在你的用户目录下(一般是 C:\Users\你的用户名),可以通过在资源管理器的地址栏输入 %appdata% 后回车快速打开 appdata 文件夹。创建一个名为 pip 的文件夹,然后在该文件夹内创建一个名为 pip.ini 的文件。

第二步:编辑配置文件

用文本编辑器打开 pip.ini 文件,在其中添加以下内容:

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

第三步:验证配置

打开命令提示符,输入 pip install 某个包,观察下载速度是否有所提升。如果配置成功,下载速度应该会比之前快很多。

📅 2024-05-15
Django启航篇

安装pip3


sudo apt-get install python3-pip

安装Django


sudo pip3 install django

验证安装

2019-03-26T06:49:38.png

创建项目


django-admin startproject convert

运行


python3 manage.py runserver

2019-03-26T07:53:45.png

📅 2020-06-30
【leetcode】5. Longest Palindromic Substring最长回文子串

5. Longest Palindromic Substring最长回文子串

解法1:中心拓展算法

思路

首先,我们知道回文串一定是对称的,所以我们可以选择一个对称中心,进行左右扩展,判断左右字符是否相等即可。

由于存在奇数的字符串和偶数的字符串,所以我们需要从一个字符开始扩展,或者从两个字符之间开始扩展,所以总共有 n+n-1 个中心。

实现代码


class Solution:

    def longestPalindrome(self, s: str) -> str:

        n = len(s)

        Max,sub = 0,s[0:1]

        for i in range(n):

            tmp = self.searchPalindrome(i-1,i+1,s)

            if len(tmp) > Max:

                Max = len(tmp)

                sub = tmp

            tmp = self.searchPalindrome(i-1,i,s)

            if len(tmp) > Max:

                Max = len(tmp)

                sub = tmp    

        return sub

    

    def searchPalindrome(self, left: int, right: int, s: str) -> int:

        sub = ""

        while left != -1 and right != len(s):

            if s[left] == s[right]:

                sub = s[left:right+1]

                left-=1

                right+=1

            else : break

        return sub

马拉车算法


class Solution:

    # Manacher 算法

    def longestPalindrome(self, s: str) -> str:

        # 特判 

        if len(s) < 2 or s == s[::-1]:

            return s



        # 得到预处理字符串

        t = "#" + "#".join(s) + "#"



        # 新字符串的长度

        t_len = len(t)



        # 数组 p 记录了扫描过的回文子串的信息

        p = [0]*t_len



        # 双指针,它们是一一对应的,须同时更新

        max_right = 0

        center = 0



        # 当前遍历的中心最大扩散步数,其值等于原始字符串的最长回文子串的长度

        max_len = 1

        # 原始字符串的最长回文子串的起始位置,与 max_len 必须同时更新

        start = 1



        for i in range(t_len):

            if i < max_right:

                mirror = 2 * center - i

                # 这一行代码是 Manacher 算法的关键所在,要结合图形来理解

                p[i] = min(max_right - i, p[mirror])



            # 下一次尝试扩散的左右起点,能扩散的步数直接加到 p[i] 中

            left = i - (1 + p[i])

            right = i + (1 + p[i])



            # left >= 0 and right < t_len 保证不越界

            # t[left] == t[right] 表示可以扩散 1 次

            while left >= 0 and right < t_len and t[left] == t[right]:

                p[i] += 1

                left -= 1

                right += 1



            # 根据 max_right 的定义,它是遍历过的 i 的 i + p[i] 的最大者

            # 如果 max_right 的值越大,进入上面 i < max_right 的判断的可能性就越大,这样就可以重复利用之前判断过的回文信息了

            if i + p[i] > max_right:

                # max_right 和 center 需要同时更新

                max_right = i + p[i]

                center = i



            if p[i] > max_len:

                # 记录最长回文子串的长度和相应它在原始字符串中的起点

                max_len = p[i]

                start = (i - max_len) // 2

        return s[start: start + max_len]

成果

2020-01-19T15:04:32.png

📅 2020-02-06
【leetcode】4. Median of Two Sorted Arrays寻找两个有序数组的中位数

【leetcode】4. Median of Two Sorted Arrays寻找两个有序数组的中位数

我的初次实现


class Solution:

    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:

        newList = nums1 + nums2

        newList.sort()

        result = 0

        if(len(newList)%2 != 0) :

            result = newList[math.ceil(len(newList)/2-1)]

        else:

            index = int(len(newList)/2)

            result = (newList[index] + newList[index-1])/2

        return result

成果

2020-01-16T13:40:45.png

问题

但是我们仔细观察,可以发现这个的时间复杂度是不够的。

📅 2020-01-22
【leetcode】2. Add Two Numbers两数相加

【leetcode】2. Add Two Numbers两数相加

描述

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:


输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)

输出:7 -> 0 -> 8

原因:342 + 465 = 807

思路

我看到这个题的第一感觉就是用递归把数获取出来,然后再相加,之后再把得数结构化。问题就被细分为了两个方面:

  1. 加数的提取

  2. 得数的结构化

我的初次实现


class Solution:

    def getStr(self,node: ListNode) -> str:

        if node.next == None:

            return node.val

        else:

            last = self.getStr(node.next)

            return  str(last) + str(node.val)



    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:

        num1 = self.getStr(l1)

        num2 = self.getStr(l2)

        result = int(num1) + int(num2)

        resultList = list(str(result))

        tmp = ListNode(int(resultList.pop(0)))

        List = tmp

        while resultList:

            tmp = ListNode(int(resultList.pop(0)))

            tmp.next = List

            List = tmp

        return List

成果

成果

📅 2020-01-16
【leetcode】3. Longest Substring Without Repeating Characters无重复字符的最长子串

题目描述

思路

查找无重复的字符子串,然后滑动窗口

初次解

每次滑动一格窗口


class Solution:

    def isUnique(self, s: str) -> bool:

        for ch in s:

            if s.count(ch) > 1:

                return False

            else:

                continue

        return True

    def lengthOfLongestSubstring(self, s: str) -> int:

        i,j,Max=0,0,0

        j+=1

        while j <= len(s):

            if self.isUnique(s[i:j]):

                print(s[i:j],"is Unique",i,j)

                Max=max(j-i,Max)

                j+=1

            else:

                i+=1

        return Max

成果

第一次优化


class Solution:

    def lengthOfLongestSubstring(self, s: str) -> int:

        if(len(s)==1): 

            return 1

        i,j,Max=0,0,0

        while j <= len(s):

            st = s[i:j+1]

            if(j+1 < len(s)):

                index = st.find(s[j+1])

                if index > -1:

                    i+=(index+1)

                j+=1

                Max=max(j-i+1,Max)

            else:

                break

        return Max

成果

2020-01-15T07:27:31.png

📅 2020-01-16

简单的python版本管理器: pyenv

pyenv可以让你轻松的在各版本的python环境中切换自如,它是一个简单而又不引人注目并遵循UNIX传统的专用工具。

这个项目是从rbenvruby-buildfork而来, 并且在配合Python的情况下做了适当的修改.

Terminal output example

pyenv能做什么?

  • 让你在用户基础上改变全局Python版本.

  • 支持为每一个项目设立一个Python版本.

  • 允许您使用环境变量覆盖Python版本.

  • 多个python环境中搜索命令,这有助于在Python版本中进行测试 tox.

与pythonbrew和pythonz相比,pyenv不能做什么?

  • 不依赖于Python本身。 pyenv是由纯shell脚本制作的。没有Python的引导问题。

  • **不需要加载到你的shell中。**相反,pyenv的shim方法的工作原理是在$ PATH中添加一个目录。

  • 不能管理virtualenv 当然你可以自行创建virtualenv virtualenv或者使用pyenv-virtualenv去自动化构建

工作原理

在较高的层次上,pyenv使用shim拦截Python命令注入PATH的可执行文件, 确定哪个Python版本已由您的应用程序指定,并传递您的命令使用你想要的Python安装版本。

理解PATH(环境变量路径)

当你执行命令,如python或者pip, 你的操作系统会搜索目录列表以查找可执行文件的那个名字.此目录列表位于环境变量中称为PATH, 列表中的每个目录使用用冒号分隔.

PATH.png

PATH中的目录从左到右搜索,因此首先匹配在列表开头的目录中的可执行文件, 然后一次往右匹配。在这个例子中,首先搜索/usr/local/sbin目录,然后搜索/usr/local/bin,然后是/usr/sbin

理解Shims(垫片)

pyenv的工作原理是在你的PATH前面插入一个shims目录,这样一来系统在搜索Python的时候第一个找到的就是pyenv管理的Python环境。这个插到最前面的路径就叫做垫片(shims)

$(pyenv root)/shims:/usr/local/bin:/usr/bin:/bin

通过一个叫做为_rehashing_的进程, pyenv维护shims目录以匹配每个已安装版本的每个Python命令,比如pythonpip等。

垫片是轻量级可执行文件,只是简单地传递命令到pyenv。所以只要安装了pyenv,当你运行时,比如说,pip,你的操作系统将执行以下操作:

  • PATH中搜索名为pip的可执行文件

  • PATH的开头找到名为pip的pyenv垫片

  • 运行名为pip的垫片,然后将命令传递给属于pyenv的pip命令

选择Python版本

执行shims程序时,pyenv会确定要使用的Python版本,并按此以下资源顺序读取:

  1. PYENV_VERSION环境变量(如果指定). 你可以使用pyenv shell 去设置环境变量在你当前shell session.

  2. 当前特定于应用程序的.python-version文件目录(如果有). 您可以使用 pyenv local修改当前目录.python-version文件.

  3. 通过搜索每个上层目录,找到第一个.python-version文件(如果有的话),直到到达文件系统的根目录

  4. 全局$(pyenv root)/version文件. 您可以使用pyenv global 修改这个文件. 如果是该全局文件不存在,pyenv假设您要使用“系统”Python。(换句话说,如果pyenv不在您的PATH中,那么任何版本都会运行.)

NOTE: 您可以同时激活多个版本,甚至包括Python2或Python3的任何版本. 这允许平行使用Python2和Python3,并且需要像tox这样的工具. 例如,要设置你的首次使用的系统Python和Python3的路径(在这个例子中设置为2.7.9和3.4.2),但也可以在你的PATH使用Python 3.3.6,3.2和2.5,首先是pyenv install缺少的版本,然后设置pyenv全局3.3.6 3.2 2.5.这时, 使用pyenv which应该能够找到每个可执行路径, 例如pyenv which python2.5(应该显示$(pyenv root/versions/2.5 /bin/python2.5) 或者pyenv which python3.4(应该显示系统Python3路径). 您还可以指定多个.python-version`文件中的版本,由换行符或任何空格分隔。

📅 2019-09-03
python3 + Django + uwsgi + nginx 配置部署笔记

本文环境

操作系统: Ubuntu 16.04.3

Python版本: 3.5.2

Django版本: 2.0.4

nginx版本: 1.10.3

本文平台为腾讯云1核1G系统

我的项目文件名为: dgutpsy

安装pip3(python3 的pip)


sudo apt-get install python3-pip

2018-04-10-20-07-25.png

安装成功后运行pip3将会出现

2018-04-10-20-09-19.png

安装uwsgi


pip install uwsgi

2018-04-10-20-17-19.png

测试uwsgi运行状态

新建文件test.py


def application(env, start_response):

    start_response('200 OK', [('Content-Type','text/html')])

    return [b"Hello World"]

有些教程说是 return "hello world"

但是这样其实会出现访问空白的情况, 我的是Python3的环境,需要对hello world进行编码.

而如果你是Python2的环境,你应该写return "hello world"

使用uwsgi运行该文件


uwsgi --http :8000 --wsgi-file test.py

此语句的意思是,使用uwsgi运行test.py文件, 采用http模式, 端口8000

2018-04-10-20-44-49.png

访问页面

好啦,可以看到亲切的hello world 就说明uwsgi运行成功了

2018-04-10-20-39-21.png

TIPS: 如果你访问不了,请先检查腾讯云安全组端口是否开放8000端口

安装Django


pip3 install Django

如在python3里面import django没有报错则安装成功.

📅 2019-01-16