博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python第九周 学习笔记(1)
阅读量:5874 次
发布时间:2019-06-19

本文共 11916 字,大约阅读时间需要 39 分钟。

描述器


get(self, instance, owner)

  • 访问属性时调用

set(self, instance, value)

  • 当对属性赋值时调用

delete(self, instance)

  • 删除属性时调用

    • self指代当前实例
    • instance是owner的实例
    • owner是属性的所属的类
  • 描述器实现前提是描述器类实例作为类属性

  • 当只实现get时 (非数据描述符),属性查找顺序是本实例优先,get方法次之
  • 当实现getset时(数据描述符) ,属性查找顺序是get方法优先

本质

  • 给类添加描述器时可以显示添加类属性,或者用setattr注入

    注意所谓的类属性不仅仅类似与x=A()的属性,类中定义的函数也是类属性

模拟staticmethod与classmethod

from functools import partialclass StaticMethod:    def __init__(self, fn):        self.fn = fn    def __get__(self, instance, owner):        return self.fnclass ClassMethod:    def __init__(self, fn):        self.fn = fn    def __get__(self, instance, owner):        return partial(self.fn, owner)class Test:    @StaticMethod    def s_mtd():  # s_mtd = StaticMethod(s_mtd)        print('s_mtd')    @ClassMethod    def c_mtd(cls):  # c_mtd = ClassMethod(c_mtd)        print('c_mtd', cls)if __name__ == '__main__':    Test.s_mtd()    Test.c_mtd()

模拟property

class Property:    def __init__(self, fget=None, fset=None):        self.fget = fget        self.fset = fset    def __get__(self, instance, owner):        return self.fget(instance)    def __set__(self, instance, value):        self.fset(instance, value)    def getter(self):        pass    def setter(self, fset):        self.fset = fset        return selfclass Person:    def __init__(self, name, age):        self._name = name        self._age = age    @Property    def name(self):  # name=Property(name)        return self._name    @name.setter    def name(self, value):  # name=Property(name).setter(name)    (value)        self._name = value    @Property    def age(self):  # name=Property(name)        return self._age    @age.setter    def age(self, value):  # name=Property(name).setter(name)    (value)        self._age = value

校验参数类型

普通装饰器

import inspectclass TypeCheck:    def __init__(self, key, type):        print('TC init')        self.key = key        self.type = type    def __get__(self, instance, owner):        print('TC get')        if instance is not None:            return instance.__dict__[self.key]        return self    def __set__(self, instance, value):        print('TC set')        if not isinstance(value, self.type):            raise TypeError        instance.__dict__[self.key] = valuedef typeassert(cls):    params = inspect.signature(cls).parameters    for name, type in params.items():        if type != type.empty:            setattr(cls, name, type.annotation)    return cls@typeassertclass Person:    name = TypeCheck('name', str)    age = TypeCheck('age', int)    def __init__(self, name: str, age: int):        self.name = name        self.age = agetom = Person('tom', 12)print(tom.name)

类装饰器

import inspectclass TypeCheck:    def __init__(self, key, type):        print('TC init')        self.key = key        self.type = type    def __get__(self, instance, owner):        print('TC get')        if instance is not None:            return instance.__dict__[self.key]        return self    def __set__(self, instance, value):        print('TC set')        if not isinstance(value, self.type):            raise TypeError        instance.__dict__[self.key] = valueclass TypeAssert:    def __init__(self, cls):        self.cls = cls    def __call__(self, name, age):        params = inspect.signature(self.cls).parameters        for key, type in params.items():            if type != type.empty:                setattr(self.cls, key, TypeCheck(key, type.annotation))        return self.cls(name, age)@TypeAssertclass Person:  # Person = TypeAssert(Person)    name = TypeCheck('name', str)    age = TypeCheck('age', int)    def __init__(self, name: str, age: int):        self.name = name        self.age = agetom = Person('tom', '12')print(tom.name)

链表


class Node:    """    Description: Node Class    attr item: current Node`s data    attr next: points to the next Node    attr past: points to the last Node    """    def __init__(self, item: object):        self.__item = item        self.__next = None        self.__past = None    @property    def item(self):        return self.__item    @item.setter    def item(self, value):        self.__item = value    @property    def next(self):        return self.__next    @next.setter    def next(self, value: object):        self.__next = value    @property    def past(self):        return self.__past    @past.setter    def past(self, value: object):        self.__past = valueclass LinkedList:    """    Description: Base class LinkedList    """    def __init__(self):        self.cur = None        self.head = None        self.length = 0    def append(self, no: object):        raise Exception('Base Method')    def iternodes(self):        raise Exception('Base Method')    def pop(self):        raise Exception('Base Method')    def insert(self, position: int, value: object):        raise Exception('Base Method')    def remove(self, value: object):        raise Exception('Base Method')class SingleLinkedList(LinkedList):    """    Description:    attr head: head Node    attr cur: current Node    method append(): append Node    """    def __init__(self):        super().__init__()    def __iter__(self):        cur_node = self.head        while True:            yield cur_node.item            if not cur_node.next:                break            cur_node = cur_node.next    def __getitem__(self, item):        cur_node = self.head        if isinstance(item, slice):            pass        else:            for _ in range(item):                cur_node = cur_node.next            return cur_node.item    def __setitem__(self, key, value):        cur_node = self.head        for _ in range(key):            cur_node = cur_node.next        cur_node.item = value    def append(self, no: object):        if self.length == 0:            self.cur = Node(no)            self.head = self.cur        else:            self.cur.next = Node(no)            self.cur = self.cur.next        self.length += 1sl = SingleLinkedList()sl.append(1)sl.append(2)for i in sl:    print(i)sl[1] = 999sl[0] = 234for i in sl:    print(i)class DoubleLinkedList(LinkedList):    """    Description:    attr head:    attr cur:    method append:    method pop:    method insert:    method remove:    method iternodes:    """    def __init__(self):        super().__init__()    def __iter__(self):        cur_node = self.head        while True:            yield cur_node.item            if not cur_node.next:                break            cur_node = cur_node.next    def __reversed__(self):        cur_node = self.cur        while True:            yield cur_node.item            if not cur_node.past:                break            cur_node = cur_node.past    def __getitem__(self, item):        cur_node = self.head        if isinstance(item, slice):            pass        else:            for _ in range(item):                cur_node = cur_node.next            return cur_node.item    def __setitem__(self, key, value):        cur_node = self.head        for _ in range(key):            cur_node = cur_node.next        cur_node.item = value    def append(self, no: object):        if self.length == 0:            self.cur = Node(no)            self.head = self.cur        else:            temp = self.cur            self.cur.next = Node(no)            self.cur = self.cur.next            self.cur.past = temp        self.length += 1    def pop(self):        pop_node = self.cur        pop_node.past.next = None        self.cur = self.cur.past        self.length -= 1        return pop_node    def insert(self, position: int, value: object):        cur_node = self.head        new_node = Node(value)        for _ in range(position - 1):            cur_node = cur_node.next        next_node = cur_node.next        cur_node.next = new_node        new_node.past = cur_node        new_node.next = next_node        next_node.past = new_node    def remove(self, value: object):        cur_node = self.head        while True:            if cur_node.item == value:                cur_node.past.next = cur_node.next                cur_node.next.past = cur_node.past                break            elif not cur_node.next:                raise Exception('NodeNotFound')            cur_node = cur_node.next    def iternodes(self, *, reverse=False):        if not reverse:            cur_node = self.head            while True:                yield cur_node.item                if not cur_node.next:                    break                cur_node = cur_node.next        else:            cur_node = self.cur            while True:                yield cur_node.item                if not cur_node.past:                    break                cur_node = cur_node.past

异常处理


产生异常

raise 异常实例
  • Python解释器自己检测到异常并引发它

异常捕获

try:待捕获异常的代码块except [异常类型] as e:异常的处理代码块else:...finally:...
  • e为异常的实例
  • 可写多个except
  • else 没有任何异常发生则执行
  • finally语句块无论如何都会执行

BaseException

  • 所有内建异常类的基类

SystemExit

  • sys.exit()引发的异常,异常不捕获处理,直接交给Python解释器,解释器退出

KeyboardInterrupt

  • 命令行使用Ctrl+C终端操作

Exception

  • 所有内建、非系统退出的异常的基类,自定义异常需要继承它

SyntaxError语法错误

  • 此错误不可捕获

ArithmeticError

  • 算术计算错误,子类有除零异常等

LookupError

  • 使用映射的键或序列的索引无效时引发的异常的基类:IndexError,KeyError

模块化


import ... 与import ... as ...

  • 找到制定的模块,加载和初始化它,生成模块对象
  • 在import所在的作用域的局部命名空间中,增加名称和上一步创建的对象关联

  • 导入顶级模块,其名称会加入到本地名词空间中(dir()),并绑定到其模块对象
  • 导入非顶级模块,至将其顶级模块名称加入到本地名词空间中,导入的模块必须用完全限定名访问
  • 如果使用as,as后的名称直接绑定到导入的模块对象中,并将该名称加入到本地名词空间中

from ... import ...与from ... import ... as ...

  • from后指定的模块名只加载并初始化,不导入
  • 对于import子句后的名称
  • 先查from导入的模块是否具有该名称属性,如果不是,则尝试导入该名称的子模块

自定义模块

  • 命名规范
  • 全小写,下划线来分割

模块搜索顺序

sys.path

  • 返回列表
  • 可被修改,追加新路径

路径查找顺序

  • 程序主目录
  • PYTHONPATH目录
  • 标准库目录

sys.modules

  • 返回字典
  • 记录所有加载的模块

模块运行

name

  • 模块名,如不指定就是文件名
  • 解释器初始化时会初始化sys.module字典,创建builtins模块、main模块、sys模块,sys.path

if name == 'main'

  • 用于模块功能测试
  • 避免主模块变更的副作用

模块的属性

  • file 源文件路径
  • cached 编译后的字节码文件路径
  • spec 显示模块规范
  • name 模块名
  • package 当模块是包,同name,否则可以设置为顶级模块的空字符串

包 Package

  • 目录下有一个init.py文件,导入包时,此文件内容代表此包

子模块

  • 包目录下的py文件、子目录都是其子模块

模块和包总结

  • 导入子模块一定会加载父模块,导入父模块一定不会导入子模块
    包是特殊的模块,包含path属性

绝对导入,相对导入

绝对导入

  • 总是去搜索模块搜索路径中找

相对导入

  • 只能在包内使用,且只能用在from中
  • . 表示当前目录
  • .. 表示上一级目录
  • ... 表示上上级目录

访问控制

  • from ... import *

    • 使用此方法导入模块时,以_和__开头的属性不会导入
  • 使用all
    • 一个列表,每个元素都是模块内的变量名
    • 定义all后,from ... import * 只导入all内的属性

包管理


  • setuptools

    • 包管理的核心模块
  • pip

    • 目前包管理的事实标准
  • wheel
    • 以二进制安装,不需要本地编译
pip install wheel

创建setup.py文件

# from distutils.core import setup  # 可能失败from setuptools import setupsetup(name='Distutils',      version='1.0',      description='Python Distribution Utilities',      author='Greg Ward',      author_email='gward@python.net',      url='https://www.python.org/sigs/distutils-sig/',      packages=['distutils', 'distutils.command'],     )
  • package内容是要管理的包

查询命令帮助

python setup.py cmd -help

build

  • 创建一个build目录
python setup.py build
  • build得到的文件,直接拷贝到其他项目就可以用

install

python setup.py install
  • 如果没有build,会先build编译,然后安装

sdist

python setup.py sdist
  • 创建源代码的分发包
  • 在其他地方解压缩这个文件,里面有setup.py,就可以使用python setup.py install安装,也可以
  • pip install XXX.zip直接使用pip安装这个压缩包

插件化开发


动态导入

  • 运行时,根据用户需求,找到模块的资源动态加载起来
  • import(name, globals=None, locals=None, fromlist=(), level=0)
    • name 模块名
    • import 本质上就是调用此函数(sys = impot('sys') 等价于import sys),但建议不直接使用,建议使用
    • importlib.import_module(name, package=None)
    • 支持绝对导入和相对导入,如果是相对导入,package必须设置

插件化编程技术

依赖的技术

  • 反射:运行时获取类型的信息,可以动态维护类型数据
  • 动态import:使用importlib
  • 多线程:可以开启一个线程,等待用户输入,从而加载指定名称的模块

加载时机

  1. 程序启动时
  2. 程序运行中
  • 如插件过多,会导致程序启动很慢,如果用户需要时再加载,如果插件太大或依赖多,插件也会启动慢。
  • 因此先加载必须、常用插件,其他插件使用时,发现需要,动态载入

基础知识补充


slot

  • 字典为了查询效率,必须用空间换时间
  • 如果实例对象数量过大,那字典占用空间过大
  • 如果类定义了slot,实例会省略建立dict
  • 如果给实例增加不在slot的属性会抛出Attribute异常
  • slot可以定义为元组或列表,通常用元组,省空间
  • slot不会继承给子类

未实现和未实现异常

  • NotImplemented是个值,单值,是NotImplementedType类的实例
  • NotImplementedError是类型,是异常,返回type

运算符重载中的反向方法

  • 当正向方法返回NotImplemented时调用反向方法

git服务器搭建


gogs

软件依赖

Mysql

安装

useradd gitsu - gittar xf gogs*cd gogsmysql -uroot -p < scripts/mysql.sql
grant all on gogs.* to 'gogs'@'%' identified by 'gogs';flush privileges;

配置文件

mkdir -p custom/confcd custom/conftouch app.ini

启动gogs

  1. ./gogs web

  2. 服务启动

    gogs下需要建立log目录

root用户操作

cp /home/git/gogs/scripts/init/centos/gogs /etc/init.d/chmod +x /etc/init.d/gogschkconfig gogs onservice gogs start

首次登陆

转载于:https://blog.51cto.com/11281400/2118365

你可能感兴趣的文章
基于域名虚拟主机及主站迁移
查看>>
linux sed
查看>>
高可用高性能负载均衡软件HAproxy详解指南-第一章(简介、安装)
查看>>
超级碗另一面:大逆转背后,你没看到的人工智能大PK
查看>>
IntelliJ Idea 常用快捷键列表
查看>>
SQL Server 2005系列教学(3) 创建数据表
查看>>
我的书也开始赚美金
查看>>
Windows Azure Storage (9) Windows Azure 上的托管服务CDN (中) Blob Service
查看>>
Redis 中的事务
查看>>
用 Subversion 构建版本控制环境
查看>>
js24---工厂模式2
查看>>
pa/patch/115/sql 下的pls文件在EBS启动的时候会去更新数据库中的pkg ?
查看>>
Windows Mobile, Windows Embedded CE工程师的海外找工经验
查看>>
MonoRail学习笔记七:页面交互的输入输出方式总结
查看>>
项目利益相关者
查看>>
android window.requestWindowFeature()常用方法
查看>>
【Javascript Demo】移动端访问PC端网页时跳转到对应的移动端网页
查看>>
走在网页游戏开发的路上(四)
查看>>
Linux内核【链表】整理笔记(2) 【转】
查看>>
android152 笔记 4
查看>>