Python基础教程-小甲鱼

基础的知识点-字符串、列表、元组、字典、集合、os、os.path

7. 小甲鱼

7.1 random

  • random
  • random.randint(1,10) : 生成1到10之间的随机数

7.2 Python的一些数值类型

  • 整形

  • 浮点型

  • python的数据类型是不受多少位的限制的 ,硬要说,限制于内存大小

  • e记法: 1e10 1e-10 这种记号统统是浮点型

  • bool: 特殊的整形

    1
    2
    True + True # = 2
    True / False # 分母是0
  • int不是向下取整,是截断处理,这样效率高

    1
    2
    int(1.2) # 1
    int(-1.2) # -1

    加0.5就四舍五入了

  • str转换浮点数的时候还是很神奇的

    image-20211120222008839

  • 推荐isinstance来判断变量类型

    1
    2
    isinstance(4,int) # True
    isinstance(4,str) # False
  • 3 < 4 < 5 这种表达式在python是行得通的

7.3 三元操作符 条件表达式

  • 和C语言的顺序有区别

    1
    small = x if x<y else y
    1
    small = x<y ? x: y;

7.4 assert断言

  • 当这个关键字后面的条件为假时,程序自动崩溃并抛出AssertionError的异常

    1
    assert 3 > 4

7.5 for循环

  • 不像C语言,python在循环体内修改循环变量,开启新一轮循环时还是上次循环的后继的

    1
    2
    3
    for i in range(4):
    i += 1
    print(i)

    输出是1 2 3 4,而不是1 3

7.6 列表: 打了激素的列表

  • 列表里的元素类型可以不一致

  • 方法

    • append():加一个进来
    • len()
    • extend(): 可以同时加多个进入来,将两个列表合并是吧
    • insert():第一个是index,第二个是element
    • number[0] : 访问元素的方式 number[-1]
    • 删除元素:
      • remove(): 元素,只会删除第一个,不存在则报错
      • del: del number[0]这种方式可以
      • pop():栈方法,但是还可以加上索引值比如pop(1),pop出number[1]
    • 切片
  • 操作符

    • 比较大小:按照字典序比较的方法比较,字符串的比较
    • 拼接 +,和extend()有点像
    • 重复 *
    • 成员关系操作符 : in not in
  • 列出方法dir(list)

  • count: 计算参数出现的次数

  • index: index(123):找123第一次出现的index,index(123,4,7)4到7(不包括7)之间第一次出现123的index,找不到会出ValueError

  • reverse: 反转列表

  • sort:默认从小到大排序,应该可以加入排序的函数吧

    • sort(func,key):排序函数和key
    • sort([func,key],rreverse=True):反转一下
  • 拷贝:

    • list11 = [1,3,2,99,7,8]

    • list12 = list11[:]

    • list13 = list11

      image-20211122105331266

7.7 元组 戴上了枷锁的列表

和列表的不同之处:元组是不可变的类型,一旦定义了就不能改变元素了

  • 修改元组的元素会抛出TypeError

  • 元组的本体应该是逗号啦

    1
    2
    3
    4
    5
    a = 1,2,3 # a是元组
    a = (1) # a不是元组
    a = (1,) # a是元组
    a = () # a是空元组
    a = 1, # a是元组

    还有函数返回 return a,b,c 也就是返回一个元组啦

  • 由于元组是不可变的,但是可以使用拷贝的方法新建一个元组来实现增删改查

    1
    2
    temp = (1,2,3,4)
    temp = temp[:2] + (1,)+temp[2:]

    注意上面的方法并不是更改了第一行定义的temp,而是通过切片取出了temp,然后进行拼接赋值给一个新的temp,第一行的那个也还是在的,不过没有标签指向它了,所以会被回收

  • 操作符:

    • 拼接: +
    • 重复: *
    • 逻辑: >
    • 成员关系: in not in
  • dir(tuple)

    • count
    • index

7.9 字符串

  • 切片:和元组、列表的切片操作是类似的

  • 字符串和元组一样不可以变

  • 但是字符串的方法十分多,因为使用频率高

    • capitalize(): 第一个字符大写,仅仅第一个,有句号也是第一个,这个有啥用?

    • casefold(): 小写

    • center(width): 居中,长度到达width,不足用’ ‘补全,长了就不变,不会截取

    • count(sub,[,start[,end]]): 返回sub在字符串中鸿出现的次数,后两个参数表示字符串索引范围

    • encode(encoding='utf-8',errors='strict'): 字符串的编码

    • endswith(sub,[,start[,end]]): 检查字符串是否以sub结尾,后两个参数表示字符串索引范围,就是检查这个子串是否以这个sub结尾

    • expandtabs([tabsize=8]):将tab(\t)转换为空格,默认为8个

    • find(sub,[,start[,end]]):没有返回-1,不像index会报错,返回的是第一个出现的

    • index(sub,[,start[,end]]):没有会报ValueError异常,其它和find一样

    • format()

    • format_map()

    • isalnum:至少有一个字符并且都是字母或者数字为True

    • isalpha():至少有一个字符并且都是字母为True

    • isascii()

    • isdecimal():至少有一个字符且只包含十进制数字返回True

    • isdigit():

    • isnumeric()

      区别

      image-20211122112937841

      isnumeric可以识别中文的,甚至于罗马等,但是不可以识别one

      image-20211122113253886

      震惊

    • isidentifier()

    • islower():小写

    • issprintable()

    • isspace(): 空格

    • istitle():单词的第一个字母是大写,其他的是小写

    • issupper():大写

    • join(sub):以字符串为分割符,插入到sub中所有的字符之间

      image-20211122113959685

    • ljust(width):左对齐,就像那个center

    • lower():大写转到小写

    • lstrip():去掉左边空格

    • rstrip():去掉右边的空格

    • maketrans():

    • partition(sub): 找到字符串sub,吧字符串分成一个三元组(之前,sub,之后),如果不包含就是(str1,’’,’’)

    • removeprefix()

    • removesuffix()

    • replace(old,new[,count]):把字符串中old字符替换乘new字符串,count表示不超过count次

    • rfind(sub[,start[,end]]):从右边的find

    • rindex(sub[,start[,end]]):从右边index

    • rpartition(sub)

    • rjust()

    • rsplit()

    • split(sep=None,maxsplit=-1): 不带参数以空格为分割符切片,maxsplit表示仅风格maxsplit个子字符串,返回一个列表,不包括分割符呀

    • splitlines([keepends]):按照’\n’分割,返回一个包含各行的列表,keepends表示返回前keepends行

    • startswith([refix[,start[,end]]]):和endswith类似

    • strip([chars]):删除左右的空格

    • swapcase():大写变小写,小写变大写

    • title(): 单词变成大写开头

    • translate(table):根据table的规则(可以由str.maketrans('a','b')制定)转换字符串中的字符

      image-20211122115534965

    • upper(): 转换字符串中的所有小写为大写

    • zfill(width),返回长度为width的字符串,源字符串右对齐,前边用’0’填充

  • 字符串的格式化

    • "{0} love {1}.{2}".format('I','python','com')

    • '{a} love {b}.{c}'.format(a='I',b='python',c='com')

    • '{0} love {b}.{c}'.format('I',b='python',c='com')

      位置参数要在关键字参数前面,比如上面这个,不可以把b或者用0

    • 0这样就不是格式化了,就像转义字符

    • '{0:.1f}'.format(23.234): 冒号表示格式化输出的开始

      • %c: '%c'%97 多个用元组括起来
      • %s
      • %d
      • %o
      • %x
      • %X
      • %f
      • %e %E
      • %g %G: 根据大小智能选择是浮点数还是科学计数法
      • 这些命令都可以类似%md占位m位
    • 辅助命令

      • m.n: m最小宽度,n小数点后位数,m可以不要的表示0
      • - 左对齐
      • + 正数前加上正号
      • #: 八进制前加上0o.十六进制前加上0x或者0X
      • 0: 空格用0填充

7.9 序列共有的一些BIF

常见方法 Built In Functions

  • list()

  • tuple()

  • str()

    image-20211122121534085

  • len()

  • max()

  • min()

  • sum(iterable[,startwith]):后面的参数不是起始点,是加法的初始值

  • sorted

  • reversed()

  • enumerate(): 加上索引的元组,看下面的例子

  • zip(): 可以不一样长

    image-20211122122547631

7.10 函数

  • 函数文档:

    1
    2
    3
    def fun():
    '函数文档'
    print('hello')

    image-20211123111040152

    这样是符合语法规范的

    1
    fun.__doc__

    调用函数,也可以使用 help来写

    只打印第一行的,后面的都不打印了

  • 收集参数

    1
    2
    3
    4
    def test(*params):
    print('参数长度',len(params))
    print('第二个参数是',params[1])
    test(1,’sdf',a,'sdf')

    如果后面还有其他参数,调用时需要使用关键字参数的形式调用

    1
    2
    3
    4
    5
    def test(*params,exp):
    print('参数长度',len(params))
    print('第二个参数是',params[1])
    a = 5
    test(1,a,'df',exp=9)
  • 函数里没有写return,会返回一个None,(NoneType), 直接return应该也是这样的

  • 函数变量的作用域: 函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量

    • 但是不要尝试在函数内部修改全局变量的值,真的要修改使用global关键字
    • 试图修改时,会使用屏蔽机制,python会自动创建一个局部变量
  • 内嵌函数和闭包

    • def fun1():
          print('--fun1正在被调用')
          def fun2():
              print('--fun2正在被调用')
          fun2()
      fun1()
      
      1
      2
      3
      4

      ```bash
      --fun1正在被调用
      --fun2正在被调用
      **内嵌函数的整个作用域都在外部函数之内,在外部函数之外就没办法调用fun2()了**
    • 闭包: 能够读取其他函数内部变量的函数

      如果在一个内部函数里对外部作用域(但不是全局作用域)的变量进行引用,那么这个函数就成为了一个闭包

      函数式编程的重要结构

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      def FunX(x):
      def FunY(y):
      return x * y
      return FunY
      i = FunX(8)
      # i是一个function
      i(5)
      # 40
      FunX(8)(5)
      # 40

      这里的FunY可以读取到FunX内部的所有局部变量(输入x也是局部变量),但是FunX不可以读取到FunY内部的局部变量

      上面这个过程就是

      输入i = FunX(8) 里面返回的式FunY,这个时候的FunY是

      1
      2
      def FunY(y):
      return 8 * y

      所以i等于上面这个函数

      再调用i这个函数就得到结果啦

      1
      2
      3
      4
      5
      6
      def fun1():
      x = 5
      def fun2():
      x *= x
      return x
      return fun2()

      注意后面那个括号:这样是会报错的,因为fun2()执行的时候要对x进行修改,所以根据前面全局变量和局部变量的关系,这里由于屏蔽的保护机制,x会被变成一个fun2内部的局部变量,但是等号右边有x,相当于还没有定义就引用了属于是

      同理下面这样也是不可以滴

      1
      2
      3
      4
      5
      6
      7
      8
      def fun1():
      x = 5
      def fun2():
      x *= x
      return x
      return fun2
      i = fun1()
      i()

      i()同样是调用fun2()对fun1()里的x进行修改,这是不可以滴

      但是容器类型是可以的,因为容器类型不是定义在栈里面的

      1
      2
      3
      4
      5
      6
      7
      8
      def fun1():
      x = [5]
      def fun2():
      x[0] *= x[0]
      return x[0]
      return fun2
      i = fun1()
      i()

      python3之后还有一个新的解决方案 nonlocal

      1
      2
      3
      4
      5
      6
      7
      8
      9
      def fun1():
      x = 5
      def fun2():
      nonlocal x
      x *= x
      return x
      return fun2
      i = fun1()
      i()

      有点像global关键字

  • lambda表达式 匿名函数

    1
    2
    def ds(x):
    return 2*x + 1
    1
    lambda x :2*x + 1

    返回一个函数对象

    1
    2
    g = lambda x,y : x + y
    g(3,4)

    两个比较常用的BIF

    • filter()

      过滤器,过滤掉非True的,返回一个可迭代对象

      1
      filter(None,[1,0,False,{},True,2])
      1
      [1,True,2]

      要自定义过滤方式,可以自己传入一个函数对象替换None

      1
      filter(lambda x : x%2 == 1,range(10))
      1
      [1,3,5,7]

      第二个参数数一个可迭代对象,第一个是一个函数,会自动对可迭代对象里的对象进行迭代,检查是True or False, 保留下来True的对象

    • map()

      map是一个映射,将一个可迭代对象按照函数规则进行迭代

      1
      2
      list(map(lambda x : x*2, range(10)))
      # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
      1
      2
      list(map(lambda x : x%2==1,range(10)))
      # [False, True, False, True, False, True, False, True, False, True]
      1
      2
      list(filter(None,map(lambda x : x%2==1,range(10))))
      # [True, True, True, True, True]

      map后面可以接收多个序列作为参数

      1
      list(map(lambda x,y : [x,y],[1,3,5,7,9],[2,4,6,8,10]))

7.11 递归

  • 递归深度

    1
    2
    import sys
    sys.setrecursionlimit(10000)

7.12 字典

  • 映射类型

  • 常见用法

    • dict(): 可以构造

      1
      2
      3
      4
      5
      dict(((1,'one'),(2:'two')))
      dict([((1,'one'),(2:'two'))])
      dict(1='one',2='two')
      dict[1] = 'One' # 有就修改值
      dict[3] = 'three' # 没有这个键就新增
    • fromkeys(): 新建字典的方法

      image-20211124110833577

    • keysvaluesitems(): 返回键s,返回值s,返回所有项(可迭代类型,dict_keys类型,dict_values类型和dict_items类型,最后一个里面的每一项是tuple,是可迭代类型但是不可以索引

    • get(key[,no]): 输入键值,如果没有就返回None或者no(可选参数),有就返回value

    • innot in : 查找值

    • clear()

    • pop, popitem: 输入是键,第一个是弹出值,第二个是键,注意这个得给参数,因为字典无序,不然就不知道弹出的是哪个了

    • setdefault: 方法使用指定的键返回项目的值。

      如果键不存在,则插入这个具有指定值的键

    • update: 更新字典的方法

      image-20211124112422247

7.13 集合

  • 没有映射关系

  • 唯一

  • 无序,所以不支持索引

  • 方法

    • 创建

      1
      2
      set1 = {1,2,3,}
      set2 = set()
    • 访问

      • 可以用for循环
      • 可以用 innot in
    • add,remove

    • 不可变集合 frozenset({1,2,3,4,5}) 不可以addremove

7.14 文件

  • 打开文件

    open(filename,mode='r')

    打开模式 执行操作
    ‘r’ 只读打开,默认的
    ‘w’ 写入的方式,会覆盖
    ‘x’ 文件已存在,会引发异常
    ‘a’ 写入的模式,存在则是追加
    ‘b’ 二进制形式
    ‘t’ 文本模式,默认的
    ‘+’ 可读写模式,可添加到其他模式中使用
    ‘U’ 通用换行符支持

    返回一个文件对象

    针对写入操作,不存在会创建

  • 操作方法

    image-20211124113658865

  • 可以用 for line in f的方式访问每一行,说明f也是可迭代对象呀

  • 文件系统

    os: 会根据操作系统自动给我们选择合适的系统操作方式

    对操作系统进行操作,随时查看吧

    函数 功能
    getcwd() pwd
    chdir(path) cd
    listdir(path=’.’) ls,返回list
    mkdir(path) mkdir
    makedirs(path) mkdir -r
    remove(path) rm
    rmdir(path) rmdir
    rmmovedirs(path) rmdir - r
    rename(old,new) mv
    system(command) 运行shell命令,返回值就是shell命令的放回值,如int
    os.curdir 不是函数,属性,当前目录
    os.pardir 上一级
    os.sep 分隔符,win是\linux是/
    os.linesep 行终止符,win是\r\n,linux是\n
    os.name 操作系统
    函数 功能
    basename(path) 文件名
    dirname(path) 路径
    join(path1[,path22[,…]]) 拼接路径,不同系统斜杆不同,所以有用
    split(path) 分离文件与路径,返回(path,name)元组
    splitext(path) 分离文件与扩展名,元组返回
    getsize(path) 字节单位大小
    getatime(path) 访问时间,秒数,可以用time模块中的localtime()或者gmtime()转换
    getctime(path) 创建时间
    getmtime(path) 修改时间
    exists(path) 是否存在
    isabs(path) 是否是绝对路径
    isdir(path) 是否目录
    isfile(path) 是否文件
    islink(path) 是否链接
    ismount(path) 是否是挂载点 比如盘符
    samefile(path1,path2) 是否指向同一个文件

7.15 pickle 模块

  • 可以将python对象转换成二进制文件的形式存储

  • 存储

    1
    2
    3
    4
    5
    import pickle
    l = [1,2,3,['df'],(1,3)]
    pickle_file = open('l.pkl','wb')
    pickle.dump(l,pickle_file)
    pickle.close()
  • 使用

    1
    2
    3
    4
    import pickle
    pickle_file = open('l.pkl','rb')
    l = pickle.load(pickle_file)
    # l就是上面哪个列表

7.16 异常处理

  • python里常见的异常
异常名称 异常解释
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

ArithmeticError

AssertionError

AttributeError

BaseException

BufferError

BytesWarning

DeprecationWarning

EnvironmentError

EOFError

Exception

FloatingPointError

FutureWarning

GeneratorExit

ImportError

ImportWarning

IndentationError

IndexError

IOError

KeyboardInterrupt

KeyError

LookupError

MemoryError

NameError

NotImplementedError

OSError

OverflowError

PendingDeprecationWarning

ReferenceError

RuntimeError

RuntimeWarning

StandardError

StopIteration

SyntaxError

SyntaxWarning

SystemError

SystemExit

TabError

TypeError

UnboundLocalError

UnicodeDecodeError

UnicodeEncodeError

UnicodeError

UnicodeTranslateError

UnicodeWarning

UserWarning

ValueError

Warning

ZeroDivisionError

  • try except机制

    1
    2
    3
    4
    5
    6
    7
    try:
    检测范围
    except Exception1 [as reason]:
    处理异常
    except Exception2 [as reason]:
    处理异常
    ...
    1
    2
    3
    4
    5
    6
    7
    8
    9
    try:
    sum = 1 + '1'
    f = open('test.txt')
    print(f.read())
    f.close()
    except OSEeeor as e:
    print('文件打开出错'+str(e))
    except TypeError as e:
    print('类型出错了'+str(e))

    如果出错的类型不在except中,还是会报红

    可以用下面这种方法,不推荐,因为这样ctrl c结束命令也变成了异常无法关闭了

    1
    2
    3
    4
    5
    6
    7
    try:
    sum = 1 + '1'
    f = open('test.txt')
    print(f.read())
    f.close()
    except :
    print('出错')
    1
    2
    3
    4
    5
    6
    7
    try:
    sum = 1 + '1'
    f = open('test.txt')
    print(f.read())
    f.close()
    except (OSEeeor,TypeError) as e:
    print('出错'+str(e))
  • try finally语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    try:
    检测范围
    except Exception1 [as reason]:
    处理异常
    except Exception2 [as reason]:
    处理异常
    ...
    finally:
    无论无何都被执行
    1
    2
    3
    4
    5
    6
    7
    8
    try:
    f = open('test.txt')
    sum = 1 + '1'
    print(f.read())
    except :
    print('出错')
    finally:
    f.close() #确保文件能够关闭了
  • 抛出异常

    1
    2
    raise ZeroDivisionError('除数为零的异常')
    raise ZeroDivisionError

7.17 else语句和with语句

  • else 不仅可以和if搭配,还可以和其他语句搭配,else语句很牛呀

  • else 和 for while循环配合使用

    image-20211125123139505

    循环里的语句全部被执行了,没有break,就会执行else,中途break就不执行else

  • else 和 异常处理的搭配 不出错就执行else,出错了就不执行else

    1
    2
    3
    4
    5
    6
    try:
    int('abc')
    except ValueError as e:
    print(str(e))
    else:
    print('没有异常')
    1
    2
    3
    4
    5
    6
    7
    8
    try:
    f= open('1.txt','r')
    print(f.read())
    except OSError as e:
    print('error')
    else:
    print("right")
    f.close()
  • with语句

    可以避免了关闭文件呀

    1
    2
    3
    4
    5
    6
    7
    8
    try:
    f = open('1.txt','r')
    for eachline in f:
    print(each_line)
    except OSError:
    print('error')
    else:
    f.close()
    1
    2
    3
    4
    5
    6
    try:
    with open('1.txt','r') as f:
    for eachline in f:
    print(each_line)
    except OSError:
    print('error')

    可以不用显式写出close文件的操作

7.18 面向对象

  • OO的特征

    • 封装
    • 继承
    • 多态
  • self是什么东西

    相当于c++的this指针

  • __init__() 魔法方法 构造方法

    在实例化方法的时候会自动调用这个方法,相当于c++的构造函数

  • 公有和私有的,默认来说,python对象的属性和方法都是共有的,当变量和函数的名字前面带上___时,就变私有了,比如__name,就得用get set方法调用,但是也是一个伪私有,仍然可以用_Person__name这种方式调用,只不过一般不这么用就完事了

  • 继承机制

    子类可以继承父类得方法和属性

    如果子类重写了父类的方法,那么父类方法就会失效,比如说子类重写了构造函数,那么就会父类构造函数里定义的一些变量就失效了,引用可能会报错

    解决这个问题可以使用如下两个方法

    • 调用未绑定的父类方法

      image-20211125225740378

![image-20211125225721904](https://gitee.com/warlock-wendell/image-bed/raw/master/blog/image-20211125225721904.png)
  • super() 这个方法更加实用

    image-20211125225913786

  • 多重继承

    1
    2
    class Child(Parent1, Parent2, Parent3):
    pass

    尽量避免使用多重继承,容易出现不可预见的bug

  • 组合:将需要的类放进去实例化就完事了

    image-20211125230505707

    没有啥继承关系的类放在一起 Mix-in机制

  • 类 类对象 实例对象

    image-20211125230645951

    类中定义的属性时静态属性,就像c++中的static属性,如果实例化对象给类对象的属性赋值了,那么对于这一个实例来说,相当于给了这个实例一个属性,覆盖了类对象里的属性,是两个不同的变量了

    属性的名字和方法的名字相同,属性会覆盖方法

    类的定义要少吃多餐,属性名名词,方法名动词

    python严格要求绑定,实例才能调用函数 就是那个self是不能省去的

    1
    dd.__dict__

    可以查看属性和方法

  • 一些相关的BIF

    issubclass(Child,Parent)

    isinstance(object,classinfo) : 第二个参数可以是一个元组

    hasattr(object,name): 对象,属性名,属性名要是字符串

    getattr(object,name[,default]): 不存在打印defalut,没有指定就会抛出属性异常

    setattr(object,name,value): 给属性赋值,如果不存在就会新建一个属性

    delattr(object,name):删除属性

    property(fget=None,fset=None,fdel=None,doc=None):通过属性设置属性

    image-20211126001859103

    可以通过操作x来实现对size变量的操作,这种对于统一接口维护更加方便

  • 析构和构造函数

    1
    __init__(self[,...])
    1
    __new__(cls[,])

    第一个调用的是__new__方法,一般不重写它,只在修改一个不可变对象时我们才重写new方法

    image-20211126004214272

    1
    __del__(self)

    垃圾回收机制工作时才会调用这个方法,del直接删除时不调用这个方法,简单的说就是所有的引用都被del了才会启动这个机制

  • 工厂函数

    类对象就是工厂函数

    比如

    1
    int('123')

    就是产生一个int对象

  • 算术操作 有点像C++的s操作符重载

    image-20211126095143019

    image-20211126095032321

    上面这样会无限递归,不可以这么写

    image-20211126095101635

    这么写时可以的

  • 对指定魔法方法进行重写,可以跳出框框

    image-20211126135221879

    反运算 : a+b 当a没有加法操作时,会去调用b的加法操作

    增量赋值:+=之类的行为

    一元操作符

    类型转换

    上边这些东西都是由函数实现的,都可以重写这些方法

  • 属性访问

    image-20211126234848011

  • property 描述符类

image-20211126235750680

  • © 2019-2022 Wendell
  • Powered by Hexo Theme Ayer

请我喝杯咖啡吧~

支付宝
微信