标签列表

everest33

自制力

导航

python3.x 学习杂记

 

※,miniconda 误删pip(pip uninstall pip)

  1. python -m ensurepip(这好像是重新安装pip)
  2. python -m pip install --upgrade pip(这好像是更新pip)
  3. 【实操】下载脚本,https://bootstrap.pypa.io/get-pip.py,然后python get-pip.py即可。

※,pip常用命令

  • python -m pip install 与直接 pip install 命令的区别:

    1 python -m pip 实际是 path/to/python.exe -m pip,即指定了python解释器的版本,如果系统里装了不同版本的python, 这个命令会明确指出为哪个版本的python安装这个包.
    2 Windows系统中, 当您执行pip install --upgrade pip时,系统会认为pip.exe正在运行,因此,Windows是不会让您覆盖pip.exe的。但是,如果您执行python -m pip install --upgrade pip,
    就可以避免这个问题,因为正在运行的是python.exe,不是pip.exe。
    ※,win10下,python -m pip install 的包缓存的位置: C:\Users\用户名\AppData\Local\pip\cache ; 可以通过7zip软件打开文件查看里面是什么包!
    ※,Linux下,pip install安装位置:~/.local/lib/python3.8/site-packages //不同的账号位置不一样(家目录不一样),而且是独立的。
  • pip config list //查看pip源
  • pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple //设置pip清华源
  • pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/ //设置pip阿里源 
    • 【windows】Writing to C:\Users\tonghuangshan\AppData\Roaming\pip\pip.ini 
    • 【Linux】      Writing to /home/sungrower/.config/pip/pip.conf 
  • pip list // 查看已安装的package
  • pip freeze // 获取全部版本依赖
  • ·pip show numpy· // 显示关于numpy包的相关信息,包括包的下载位置
  • pip缓存
    • pip cache dir //获取pip缓存的位置
    • pip install --no-cache-dir <package> // 在不使用缓存的情况下安装软件包
    • pip cache remove matplotlib:从 pip 的缓存中删除所有与 matplotlib 相关的车轮文件。
    • pip cache purge:从 pip 的缓存中清除所有车轮文件
  • 查看包的版本
    • python -m pip install numpy== //通过报错信息来查看numpy包都有哪些版本,已过期,老版本pip可以使用!
    • pip index versions <package-name> // 查看包的所有版本。
      • 注意不同的python版本支持的包的版本也不一样,比如python3.8支持ray只到2.10版本,python3.10可以支持ray的2.23版本
  • pip install numpy==1.19.0 #安装指定版本的包,不加版本则安装最新版本
  • pip install -i https://mirrors.aliyun.com/pypi/simple/ numpy // 指定源。这种只对当前安装对命令有用,如果需要全局修改,则需要修改配置文件。
    Linux/Mac os 环境中,配置文件位置在 ~/.config/pip/pip.conf(如果不存在创建该目录和文件,另外这个位置也可以~/.pip/pip.conf):
    mkdir ~/.config/pip/pip.conf
    打开配置文件 ~/.config/pip/pip.conf,修改如下:
    
    cat > ~/.config/pip/pip.conf << EOF
    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple
    [install]
    trusted-host = https://pypi.tuna.tsinghua.edu.cn
    EOF
    
     国内python安装源(即pip使用的安装源):
        - 阿里云 https://mirrors.aliyun.com/pypi/simple/
        - 豆瓣 https://pypi.douban.com/simple/
        - 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
        - 中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/
        - 华中科技大学 https://pypi.hustunique.com/
  • pip uninstall numpy // 卸载numpy包. (numpy 1.19.4包有bug)
  • pip install -r requirements.txt //-r, --requirement <file>    Install from the given requirements file. This option can be used multiple times.

※,查看某个包依赖的其他包版本:pipdeptree -p torch

※,miniconda的安装与卸载与升级

Anaconda与conda、pip与conda的区别

安装

官方下载地址:点此。直接运行脚本安装即可。安装完后提示,If you'd prefer that conda's base environment not be activated on startup,set the auto_activate_base parameter to false: ·conda config --set auto_activate_base false·。

卸载:参考此文

Linux卸载过程: 安装在~/miniconda3目录下
rm -rf ~/miniconda3
编辑~/.bash_profile,删除miniconda的相关配置
rm -rf ~/.condarc ~/.conda ~/.continuum

升级miniconda对应的python版本:可以通过miniconda安装更新的python:./Miniconda3-py310_24.4.0-0-Linux-x86_64.sh -u即可。

※,记录一次在ubuntu20.04LTS上创建虚拟环境运行pytest代码的过程(python3.9)

  • cd /root/tong/pytest1/enstellar-api-autotest
  • python -m venv .venv //创建虚拟环境
    [root@167 enstellar-api-autotest]$ll .venv
    总用量 24
    drwxr-xr-x  5 root root 4096 11月 23 11:07 ./
    drwxr-xr-x 10 root root 4096 11月 23 11:07 ../
    drwxr-xr-x  2 root root 4096 11月 23 11:07 bin/
    drwxr-xr-x  2 root root 4096 11月 23 11:07 include/
    drwxr-xr-x  3 root root 4096 11月 23 11:07 lib/
    lrwxrwxrwx  1 root root    3 11月 23 11:07 lib64 -> lib/
    -rw-r--r--  1 root root   81 11月 23 11:07 pyvenv.cfg
  • .venv/bin/pip install -r requirements.txt //安装本项目需要的依赖,安装后位于.venv/lib/python3.9/site-packages
  • .venv/bin/python xxx.py //正常运行py启动脚本

※,python的类型注解

  • https://mp.weixin.qq.com/s/0Qk3XWgdVnoYWS_EnVCqyw
  • 官方文档
  • Annotation.py
    # -*- coding: utf-8 -*-
    """
    类型注解的作用:
    def get_item(key: K, container: Dict[K, V]) -> V:
        # ...
    
    def get_item(key, container):
        # ...
    上面两个函数功能完全相同,但是没有类型注解的那个,显然需要花更多的时间阅读函数内部的代码,去确认函数到底干了什么。
    并且它也无法利用编辑器的类型检查,在早期帮助排除一些低级错误。
    """
    
    # 如果你用的是 Python 3.9+ 版本,甚至连 typing 模块都不需要了,内置的容器类型就支持了复合注解:如list[int]而不须List[int]
    from typing import Sequence, NewType, Tuple, Callable, Any, Protocol, Optional, Union, Literal, TypeVar, List, Dict
    
    # 类型别名
    vector2d = Tuple[int, int]
    '''
    自定义类型。类似类型别名,但是有所区别:
    NewType创建的是原始类型(Tuple[int, int, int])的“子类”.
    所以如果一个变量类型定义为vector3d,则必须是用此类型构建出来的对象实例才能通过类型检查,
    而使用Tuple[int, int, int]类型的对象如(1,2,3)是不能通过类型检查的
    '''
    vector3d = NewType("v3d", Tuple[int, int, int])
    
    
    def foo(bar: str) -> str:
        return f"a global fooTong function with parameter bar: {bar}"
    
    
    class Person(object):
        """
        编程习惯:成员变量统一放在前部
        """
        # 定义Person类的public属性(public成员变量)
        attr1 = "attr1Value"
        # 定义Person类的private属性
        __attr2 = "attr2Value"
    
        '''不定义这些None也行,但是为了类的阅读,建议把成员变量完成的列出在类的前部'''
        __hobbies = None
        __age = None
        name = None
    
        # Literal 即字面量。它在定义简单的枚举值时非常好用,比如:
        __MODE = Literal['r', 'rb', 'w', 'wb']  # 类型别名
    
        """ 
        Person类的构造函数。也可以在构造函数中定义Person类的共有和私有属性
        """
    
        def __init__(self: 'Person', name: str, age: int):
            self.__age = age  # Person类的private成员变量
            self.name = name  # Person类的public成员变量
    
        """类实现了__call__接口,则其实例和普通的函数一样,也是可调用的(callable)"""
    
        def __call__(self, arg, *args, **kwargs):
            print("You are calling an instance of class Person. arg: {}, args:{};kwargs:{}".format(arg, args, kwargs))
    
        # def __call__(self):
        #     print("You are calling an instance of class Person. arg: {}, args:{};kwargs:{}")
    
        def getAttr2(self):
            return self.__attr2
    
        def getAge(self: "Person") -> str:
            return f'My age is {self.__age}'
    
        """
            Sequence:在某些情况下,不需要严格区分参数到底是列表还是元组(这种情况还蛮多的),
            这时候就可以将它们的特征抽象为更泛化的类型(泛型),比如 Sequence(序列)。
        """
    
        def setHobbies(self: "Person", hobbies: Sequence[str]) -> None:
            self.__hobbies = hobbies
    
        def getHobbies(self: "Person") -> str:
            return f'My hobbies are(is) {self.__hobbies}'
    
        # Optional[str]表示str类型或None类型。 Optional[str] === Union[str, None]
        def optionalTest(self: "Person", a: int) -> Optional[str]:
            if a == 1:
                return "good"
    
        # union[str, int]表示str或int中的一种。如果输入是str,返回是int也能通过类型检查,可能不是我们需要的,所以需要泛型
        def unionTest(self: "Person", param: Union[str, int]) -> Union[str, int]:
            return param
    
        def open_helper(self, file: str, mode: __MODE) -> str:
            pass
    
        def vector2dTest(self: 'Person', vector2d: vector2d):
            print(f'person.vector2dTest: {vector2d}')
    
        def vector3dTest(self: "Person", vector3d: vector3d) -> None:
            print(f'person.vector3dTest: {vector3d}')
    
        '''函数成功执行完毕,则默认会返回一个None,而不是NoReturn。注意区别。下面的函数是NoReturn'''
    
        # def foo1(self) -> NoReturn:
        #     raise RuntimeWarning("Oh,no...")
    
        def call(self: "Person", callable: Callable, arg, *args, **kwargs) -> Any:
            return callable(arg, *args, **kwargs)
    
    
    """
    Protocol:即协议。我们通常说一个对象遵守了某个”协议“,意思是这个对象实现了”协议“中规定的属性或者方法
    """
    
    
    # 一个类继承了Protocol(类型注解中的一个类),则只要实现了此类的方法都可视为此类的类型
    class Proto(Protocol):
        def foo(self):
            pass
    
    
    class A:
        def foo(self):
            pass
    
    
    class B:
        def bar(self):
            pass
    
    
    def ProtocolTest(a: Proto):
        pass
    
    
    # 类型检查通过! A()实现了foo,所以A()可以视为Proto类型
    ProtocolTest(A())
    # 类型检查不通过! B()没有实现foo,所以B()不能视为Proto类型
    ProtocolTest(B())
    """END Protocol"""
    
    """START 泛型"""
    # 定义泛型 T: T必须是str 或 int 中的其中一种。两个T必须名称一致
    T = TypeVar("T", str, int)
    
    
    def genericTest(a: T, b: T) -> List[T]:
        return [a, b]
    
    
    # 泛型类型检查不通过
    print(genericTest(18, "晴雯"))
    # 泛型类型检查通过
    print(genericTest("18", "晴雯"))
    
    '''泛型示例二'''
    """
    代码中定义了两个泛型 K 和 V,对它两的类型没有做任何限制,也就是说可以是任意类型。
    函数 get_item() 接受两个参数。这个函数不关心参数 container 字典的键是什么类型,或者字典的值是什么类型;
    但它的参数 container 必须是字典,参数 key 必须与字典的键为同类型,并且返回值和字典的值必须为同类型。
    仅仅通过查看函数的类型注解,就可以获得所有这些信息。
    """
    K = TypeVar("K")
    V = TypeVar("V")
    
    
    def getItem(key: K, container: Dict[K, V]) -> V:
        return container[key]
    
    
    dict1 = {"age": 333}
    dict2 = {(1, 3): "Tonus"} # 字典键值须是不变的类型,如str, int, tuple等
    # 例一: 类型检查通过
    getItem("age", dict1)
    # 例二: 类型检查通过,但是运行时会报错,因为没有name键
    try:
        # try语句话出现了异常之后,后面的语句不会再执行
        print(getItem("name", dict1))
        print("###### Test whether this line runs ########")  # 上一行出错后,此行将不会被执行
    except KeyError:
        print("No Such Key: %s" % "name")
    # 例三: 类型检查不通过,运行时也会报错
    # print(getItem(333, dict1))
    # 例四:类型检查通过
    print(getItem((1, 3), dict2), end="##\n")
    
    
    """END 泛型"""
    
    if __name__ == "__main__":
        p: Person = Person("TOnus", 333)
        print("##%s##" % p.attr1)
        # print("##%s##" % p.__attr2()) # Person类外无法访问私有属性__attr2
        print("##%s##" % p.getAttr2())
    
        print("My name is {1}, my age is {0}".format(p.getAge(), p.name))
    
        print(p.getHobbies())
        p.setHobbies(["抽烟", '喝酒', '烫头'])
        print(p.getHobbies())
    
        # 类型别名
        p.vector2dTest((1, 3))
        # p.vector2dTest(vector2d((1,2))) #报错
    
        # 自定义类型v3d:必须是vector3d的实例才能通过类型检查,原始类型(Tuple[int, int, int])无法通过类型检查
        p.vector3dTest((11, 22, 33))  # 无法通过类型检查,但是不影响运行
        p.vector3dTest(vector3d((1, 2, 3)))
    
        # 调用类实例:类实现了__call__接口则和普通函数一样是可调用的。
        # p(1, 2, 3, {8: "Tong"}, {(66, 88): "huangshan"}, age=33, hobbies=['smoke', 'drink wine', 'hairPerm'])
        p.call(p, 1, 88, c=3)
        print(p.call(foo, 33))
        print(p.call(p.vector3dTest, 33))

※, anaconda
    1. 安装完anaconda(安装目录D:\software)后,需要将如下路径添加进PATH中
        + D:\software\anaconda3
        + D:\software\anaconda3\Library\bin
        + D:\software\anaconda3\Scripts
    2. 记录一个问题
        pycharm中一个python工程,创建了venv并启用后,使用pip安装python包时报错:pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available。无法下载任何python包。
        但是使用Anaconda Prompt的命令行窗口pip install可以成功安装python包。在两个环境下分别输入命令path查看环境变量,发现Anaconda Prompt窗口的环境变量多了 D:\software\anaconda3\Library\bin 和 D:\software\anaconda3\Scripts(其实还有这两个目录的一些子目录).
        在win10系统的环境变量中添加了这两个路径,打开一个新的terminal,发现还是不行。重启pycharm,然后就可以了。
        【总结】新增环境变量后,pycharm的只有重启后才能生效,重新打开新的terminal是不生效的。
    
※, vscode启用虚拟环境(虚拟环境避免了全局环境出现不同版本的包从而产生的混乱):
    1. py -3 -m venv .venv // 初始化虚拟环境时使用,初始化之后便不再需要此命令
    2. Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process --Scope CurrentUser
    3. .venv\Scripts\activate
    4. 在虚拟环境下直接输入 deactive 退出虚拟环境
 ※, python http server
    - python -m CGIHTTPServer 8080  // python2
    - python -m SimpleHTTPServer 9191 // python2
    - python -m http/server 8080 --cgi //python3
    - python -m http.server 8080 --cgi //python3 windows

※,vscode中的pylint安装路径

  • vscode和pycharm的环境变量有些差异,可以通过打印sys.path来查看不同的环境变量。vscode的环境变量有一个是:C:\Users\Everest\AppData\Roaming\Python\Python39\site-packages;通过vscode的提示框安装的pylint的安装路径就在这个文件夹下。

※,★★★★★python中 import 的使用方法(包的引入):

  • 首先,python查找模块需要搜索的路径为·sys.path·下所有的目录。sys.path是指定模块的搜索路径的字符串列表 。
    • sys模块包含了与python解释器和它的环境有关的函数, 里面有个 sys.path属性。它是一个list.默然情况下python导入文件或者模块的话,他会先在sys.path里找模块的路径。如果没有的话,程序就会报错。
  • sys.path下的路径包含如下:
    • 脚本所在文件夹(当前文件夹),亦即sys.path[0],此列表的第一项,在程序启动时初始化,是包含用来调用Python解释器的脚本的目录。如果脚本目录不可用(例如,如果解释器被交互式地调用,或者脚本是从标准输入读取的),path[0]是空字符串,它引导Python首先在当前目录中搜索模块
    • 标准库:(自己用的是anaconda,标准库路径为:D:\software\anaconda\Lib)
    • 第三方库:标准库Lib目录下的site-package目录。(D:\software\anaconda\Lib\site-packages)
  • 修改sys.path的方法:
    • 动态加入:sys.path.append("mypath")。即时生效的方法,在模块里面修改sys.path值,这种方法修改的sys.path作用域只是当前进程,进程结束后就失效了。
      • 当出现ModuleNotFoundError的错误时,就是因为sys.path中没有包含进去包所在的目录。
      • 添加的path可以使用sys.path.append(os.getcwd())。关于当前工作路径和当前文件路径的区别,参考此文
      • pycharm中os.getcwd()的返回结果是由配置Working directory确定的。
    • 添加.pth文件:在site-packages/ 增加一个路径文件,如mypkgpath.pth,必须以.pth为后缀,将模块的路径写进去,一行一个路径,写上要加入的模块文件所在的目录名称。这种方法一劳永逸, 简单暴力。
    • 设置系统环境变量·PYTHONPATH·,在这个环境变量中输入相关的路径,不同的路径之间用分号分开。路径会自动加入到sys.path中。(实测可以)。
  • 文件夹下含有 ·__init__.py·文件的会被识别为python的包,又叫模块module。(另注:在python3.9 pycharm环境下测试,不使用__init__.py文件也能直接导入文件或变量)
    • __init__.py 文件除了可以将文件夹标志为module以外,还可以在其中定义或者引入变量、类、函数等,这些属于module级别的变量、类、函数等。在此文件中定义或导入的变量可以直接使用module前缀被使用。
  • 引入各层级模块(目录)的方法
    • 从工作区根目录一级一级引入
    • 使用sys.path进入某个目录,然后引入此目录下的各个包。比如引入上级目录中的某个包可以使用此种方式!
  • 可以如下使用import:
    • ·import module`:此时可以使用 属于module级别的变量myVar,使用方法:带着module前缀,print(module.myVar)
      • `import ...`此种方式引入最深只能引入到文件级别,且使用时必须带着前缀。可以取别名(取别名后原名称不再可用)。
    • `from module import myVar` // 引入module级别的变量myVar。使用方法:直接使用,print(myVar).
      • `from ... import xxx` 此种方式引入最深可以引入到代码级别(文件中的变量、方法等都可以)。使用时直接用from ... import 后的名字即可。可以取别名(取别名后原名称不再可用)
    • `from module import myFile` // 引入module下的某个python文件,此时使用文件中的函数、变量、类等需要带着文件名,print(myFile.myVar)
    • `from module.myFile import myVar` //引入module下myFile中的某个变量,使用方法:直接使用,print(myVar)
    •  
  • 如果从两个不同的地方引入了名称相同的变量,那么后引入的会覆盖前面引入的。
  • 相对引入、绝对引入等其他知识点:参考此文章

※,

★,杂记:

posted on 2019-12-04 21:42  everest33  阅读(279)  评论(0编辑  收藏  举报