# -*- coding: utf-8 -*- print('*'*20, '列表环节', '*'*20) # append()函数向列表末尾添加一个元素. # extend()函数向列表末尾添加多个元素. # insert(n,xxx)函数向列表中第n个元素前插入一个元素. L = [] for i in range(0, 5): L.append(i) print(L) L.insert(1, 5) L.insert(2, '5') L.extend([8, '10']) print(L) # remove()函数表示从列表中删除某个元素. # del()函数也表示从列表中删除某个元素. # pop()函数从列表中取出最后一个元素. if i in L: if i == 1: L.remove(1) if i == 8: index = L.index(8) del L[index] if i == 4: L.pop(-3) L.insert(3, 1) print(L) L.pop(3) L.append(1) L.extend(['111', 1]) print(L) # 列表分片. print(L[0:5]) # 列表进行拷贝. mix = L[0:5] print(mix) # 比较 *** 作符. print(L > mix) # L 包含了 mix # 成员关系 *** 作符. print('111' in L) # dir(list)可查看所有列表的 *** 作函数(方法). # print(dir(L)) print(L.count(1)) # 列表中出现3次1. print(L.index(1)) # index()函数可索引列表元素. K = L[3:7] # print(dir(K)) # print(dir(K.reverse())) K.reverse() print(K) # sort()将列表中元素从小到大排序. K.sort() print(K) print('*'*20) # 关于分片'拷贝'概念的补充. K.reverse() list11 = K list22 = list11 list33 = list11[:] print(list11) print(list22) print(list33) print('*'*20, '分片“拷贝”概念的补充.') # 注:list22=list11相当于多了个指向列表的标签,list12 = list[:]是实实在在的拷贝 list11.sort() list11.append('222') list11.insert(0, '0') # 查看id可知.list22=list11相当于多指向,id相同. print(list11, id(list11)) print(list22, id(list22)) print(list33, id(list33)) print('*'*20, '列表环节', '*'*20) print('*'*20, '元组环节', '*'*20) # 元组和列表是近亲关系,所以在实际使用上是非常类似的. T = (5, 4, 3, 2, 1) print(T) # 元组的分片. print(T[:2]) # 更新和删除一个元组. # 注:其并未对原元组进行修改,而是生成了一个新的元组,并贴上temp名字标签而已。原元组由于标签没有了,则会被自动回收。 T = T[:2] + (10, ) + T[2:] print(T) del T # 注:元组不允许修改和删除。 # 格式化. print('%5.2f' % 27.625) # 序列!!! T = (4, 3, 2, 1) print(T) # max() 返回序列或者参数集合中的最大值. # min() 返回序列或者参数集合中的最小值. print(max(T), min(T)) # sum(iterable[,start=0]) 返回序列iterable和可选参数start的总和. print(sum(T), sum(T, 5)) # sorted()将元素从小到大重新排列.(注:元组是不可以修改和删除的,所以不可以直接对元组使用sorted与reversed命令) print(sorted(T)) # 以列表的形式返回,并进行了排序. # reversed()将元素倒序排列. # print(dir(reversed)) print(reversed(sorted(T))) # 返回一个列表倒序对象. # for i in reversed(sorted(T)): # print(i) print(list(reversed(sorted(T)))) print(reversed(T)) print(tuple(reversed(T))) # for i in reversed(T): # 返回一个元组倒序对象. # print(i) # enumerate()将每个元素插入枚举. num = sorted(T) # print(dir(enumerate(num))) # 具备'__iter__'、'__next__',则是一个迭代器,可以进行遍历输出. print(enumerate(num)) # 返回一个对象.也可以用遍历的方式把内容遍历出来. print(list(enumerate(num)), '对象', tuple(enumerate(num))) for i in enumerate(T): print(i[0], num[i[0]]) # zip()返回由各个参数的序列组成的元组. nam = sorted(T)[:] # 进行'分片'拷贝,实实在在的拷贝,不是让列表指向多个标签. # print(num, nam) # print(list(reversed(num))) print(zip(list(reversed(num)), nam)) # 返回一个zip()对象. print(list(zip(list(reversed(num)), nam)), '对象', tuple(zip(list(reversed(num)), nam))) print('*'*20, '元组环节', '*'*20) # 关于函数收集参数. def test(*params): print('参数的长度是:', len(params)) print('第二个参数是', params[1]) test(1, 2, 3, 4, 5, 6) def back(): print('255') return [7, 8, 9] # back() # print(back()) B = back() # B = back()实例化对象。返回:函数内容. print(B, '返回值', B[2]) # 返回:函数的返回值. # 内嵌函数和闭包. # 内嵌函数. def fun1(): print('fun1()被调用') def fun2(): print('fun2()被调用') def fun3(): print('fun3()被调用') fun2() return fun3 # print(fun1().__dir__()) # fun1() print(fun1()) # f = fun1() # print(f) # 返回函数fun3方法对象. # 闭包. def ind(x): def fun11(y): return x * y return fun11 print(ind(5)(8)) # ind = ind(5) # print(ind(8)) # nonlocal语句将x强制为不是局部变量. def non(): x = 5 def non1(): nonlocal x x *= x return x return non1() print(non()) # global可将局部变量声明为全局变量. count = 5 def fun4(): global count count = 10 print(count) fun4() print(count) # 匿名函数:lambda表达式. g = lambda x: 3 * x + 2 # 相当于 def 匿名(x): return 3 * x + 2. print(g(3)) # 过滤函数filter()可筛选出非零元素. # filter函数接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False, # 最后将返回 True 的元素放到新列表中,就好比是用筛子,筛选指定的元素; # 语句:filter(function, iterable) T = (None, [1, 0], True, False) print(type(T)) print(filter(None, [1, 0, True, False])) # 返回一个filter对象. # print(filter(lambda x: x % 2, [1, 2, 3, 4, 5])) print(list(filter(lambda x: x % 2, [1, 2, 3, 4, 5]))) print(list(filter(None, [1, 2, 3, 0, 5]))) # print(dir(filter(None, [1, 0, True, False]))) # 查看对象属性(方法). # for i in filter(None, [1, 0, True, False]): # 对对象进行遍历. # print(i) # print(list(filter(None, [1, 0, True, False])), '对象', tuple(filter(None, [1, 0, True, False]))) def is_odd(n): return n % 2 == 1 tmp = filter(is_odd, range(10)) print(tmp) print(list(tmp)) print('*'*20) # iter()函数和next()用来生成迭代器. ls = [1, 2, 3, 4, 5] # print(dir(lis)) it = iter(ls) print(it) # 列表形式的迭代器对象. print(next(it)) print(next(it)) for i in it: print(i, end=' ') print('*'*20) ls = [1, 2, 3, 4, 5] it = iter(ls) while True: try: x = next(it) print(x, end=' ') except StopIteration: # 遇到StopIteration就退出循环 break print('*'*20) class MyNumbers(object): def __iter__(self): self.a = 1 return self def __next__(self): global x x = self.a self.a += 1 return x myclass = MyNumbers() # 实例对象. myiter = iter(myclass) # 创建迭代器对象. print(next(myiter)) print(next(myiter)) print(next(myiter)) print('*'*20) class MyIter(object): # 我限制循环次数,超出则抛出错误. def __iter__(self): self.a = 1 return self # 返回实例对象 def __next__(self): global x x = self.a self.a += 1 if x >= 3: raise StopIteration('抛出一个异常') # 异常抛出print()不会执行. else: return x My = MyIter() # 实例对象. ie = iter(My) # 创建迭代器对象. # print(next(ie)) # print(next(ie)) # print(next(ie)) # 第三次时会出错. for i in ie: print(i) print('*'*20) class ItIter(object): # 类似于上面while为了防止报错. def __iter__(self): self.a = 1 return self def __next__(self): global x x = self.a while True: self.a += 1 try: if x >= 3: raise StopIteration('抛出一个异常') else: return x except StopIteration: break return MyIe = ItIter() Ie = iter(MyIe) print(next(Ie)) print(next(Ie)) print(next(Ie)) print('*'*20) # 生成器内容. def func(): print('内容1') yield 1 print('内容2') yield 2 print('内容3') f = func() print(f) # 返回一个迭代器对象.然后用迭代器next()方法输出.不用进行iter()方法进行创建迭代器对象. # print(dir(f)) print(next(f)) print(f.__next__()) # print(f.__next__()) # 也报错了,没有迭代器对象了. # print(f.__next__()) # 再次运行则报错. print('*'*20) import sys def fib(n): global x x = 0 while True: if n < 0: print('不能为负数.') yield n if x <= n: print('内容%s' % x) # 为了更加方便观察. yield x # 返回一个迭代器对象. else: return # 上半部分主要用于形成迭代器对象. x += 1 ib = fib(-1) print(ib.__next__()) ib = fib(2) print(ib.__next__()) print(ib.__next__()) print(ib.__next__()) # print(ib.__next__()) # 这次报错. print('*'*20) ib = fib(2) print(ib) # 返回一个迭代器对象. # print(dir(ib)) # 查看对象的属性(方法). # for i in ib: # for循环直接遍历出来. # print(i) while True: try: print(next(ib)) except StopIteration: # sys.exit() # 直接结束python让后续的命令不能运行. break print('*'*20) # 生成器表达式. # collections是一个包含了许多类型的module包 from collections.abc import Iterator, Iterable, Generator g = (i**2 for i in range(1, 6) if i > 3) # 返回一个迭代器对象. print(g) # print(isinstance(g, Iterable)) # 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象. # print(dir(g)) # print(next(g)) for i in g: print(i, end=' ') print('*'*20) # print(dir(list)) # 只含有__iter__为可迭代对象. ls = [1, 2, 3] # 可以看到这是一个可迭代对象但并不是迭代器,我们把它搞成一个迭代器试试看. print('迭代器对象:', isinstance(ls, Iterator), '可迭代对象', isinstance(ls, Iterable), '生成器:', isinstance(ls, Generator)) def generator_list(a): for e in a: yield 'Province:\t' + str(e) for province in generator_list(ls): print(province) gen = generator_list(ls) print(gen) print(isinstance(generator_list(ls), Iterator), isinstance(generator_list(ls), Iterable), isinstance(generator_list(ls), Generator)) # print(dir(generator_list(ls))) print(next(gen)) print(next(gen)) print(next(gen)) # print(ls) # 可迭代对象.具备__iter__属性(方法). lls = iter(ls) # iter()方法的用处.第一个参数需要是具备属性可迭代对象的变量. # print(dir(lls)) # 迭代器对象.具备'__iter__'、'__next__'属性(方法). print('*'*20) class TextIter(object): def __init__(self): self.a = [1, 2, 3] self.b = iter(self.a) # 迭代器对象. def __iter__(self): print('__iter__方法') return iter(self.a) # 返回迭代器对象. def __call__(self): item = next(self.b) print('__call__方法') return item # 返回迭代器函数next(). # print(dir(TextIter)) T = TextIter() # 创建实例对象. # print(dir(T)) print(T) # TextIter类的实例对象具备__iter__则是可迭代对象. print(callable(T)) # 注意这里是True # for i in T: # 对可迭代对象进行遍历. # print(i) T1 = iter(T) # T1是迭代器对象. # print(dir(T1)) # 迭代器对象. # 没有__call__方法. print(T1) print(callable(T1)) # 注意这里是False # print(T1.__next__()) # print(T1.__next__()) # print(T1.__next__()) # print(T1.__next__()) # 运行到第四次则报错. # for i in T1: # 对迭代器对象进行遍历. # print(i) T2 = iter(T, 3) # T必须是callable,否则无法返回callable_iterator print(T2) for i in T2: print(i) print('*'*20) class MyIterable(object): # 可迭代对象. def __init__(self, a): self.a = a self.b = [1, 2, 3] self.c = iter(self.b) def __iter__(self): return MyIterator(self.a) # 返回迭代器对象.差不多返回MyIterator类的实例对象. My = MyIterator(self.a) def __call__(self, *args, **kwargs): ite = next(self.c) return ite class MyIterator(object): # 迭代器对象. def __init__(self, abb): self.abb = abb self.app = 0 def __iter__(self): # 返回本实例对象. return self def __next__(self): global x x = self.app while True: self.app += 1 # try: if self.app > self.abb: raise StopIteration('抛出一个错误') else: return x # except StopIteration: # # break # print('错误') fn = MyIterable(5) # 创建MyIterable实例对象. # print(dir(fn)) # 可迭代对象. print(fn) # print(list(fn)) # print(next(fn)) # 这里是一个错误问题,展示给你们看.记住fn是可迭代对象,不是迭代器对象. # 然后我们先尝试可迭代对象的运用. for i in fn: # for循环自带抛出错误后就停止 print(i) # print(dir(iter(fn))) # 迭代器对象. print(iter(fn)) # 可以先赋值给一个变量,然后运行迭代器next()方法.然后运行输出. itt = iter(fn) # print(dir(itt)) # print(itt.__call__()) # print(callable(itt)) # 不是一个可调用对象. print(itt.__next__()) print(itt.__next__()) # print(itt.__next__()) # print(itt.__next__()) # print(itt.__next__()) # print(itt.__next__()) # for i in itt: # print(i) Itt = iter(fn, 3) # 返回一个callable_iterator对象. print(Itt) for i in Itt: print(i) print('*'*20) class MyRange(object): # 实现和range()语句一样的效果. def __init__(self, *params): self.step = 1 # self.start = params[0] # 开始 # self.stop = params[1] # 结束 # self.step = params[2] # 步长 assert type(params) == tuple if len(params) == 0: raise TypeError('range参数不能为0') if len(params) > 3: raise TypeError('range参数只有3个') assert len(params) >= 1 and len(params) <= 3 # 上面是上边界. if len(params) == 1: # 一个参数的时候. self.start = 0 # 默认起始为零 if params[0] <= 0: self.stop = 0 else: self.stop = params[0] elif len(params) == 2: # 两个参数的时候. # self.start = params[0] # 开始 # self.stop = params[1] # 结束 # if params[0] >= 0: if params[0] < params[1]: self.start = params[0] self.stop = params[1] else: # 让他返回一个空 self.stop = 0 self.start = 0 # else: # self.start = params[0] # self.stop = params[1] else: # 传入三个参数开始、结束、步长. assert len(params) == 3 # 确认传入的参数是3个. if params[2] == 0: # range(0, 5, 1) raise ValueError('range() arg 3 must not be zero') elif (params[0] < params[1] and params[2] > 0) or (params[0] > params[1] and params[2] < 0): self.start = params[0] self.stop = params[1] self.step = params[2] else: self.start = 0 self.stop = 0 self.start -= self.step self.stop -= self.step def __iter__(self): return self # 返回当前实例对象.对象里面包含一些你对其实例对象进行的一些效果. def __next__(self): assert self.step != 0 # 步长不能为0. if self.step > 0: if self.start >= self.stop: raise StopIteration self.start += self.step return self.start else: # 步长小于0. if self.start <= self.stop: raise StopIteration self.start += self.step return self.start print(list(range(5))) print(list(MyRange(5))) print('*'*20) print(list(range(0, 5))) print(list(MyRange(0, 5))) print('*'*20) print(list(range(-5, 5, 2))) print(list(MyRange(-5, 5, 2))) print('*'*20) print(list(range(5, -5, -2))) print(list(MyRange(5, -5, -2))) # 生成器. Str = '456' Float = 1.0 Int = 1 # 可知可迭代对象. print(isinstance(Str, Iterable), isinstance(Float, Iterable), isinstance(Int, Iterable)) List = [] Dict = {} print(isinstance(List, Iterable), isinstance(Dict, Iterable)) # 列表和字典都是可迭代对象. # 和下面是一样的,只是为了了解清楚怎么运行的. # yield_list = [1, [4, 5], [[8]], [7, 8, 9], 10] # # # def flatten(n): # try: # for i1 in n: # # print(i1) # for ii in flatten(i1): # [4, 5] # # print(ii) # yield ii # except TypeError: # yield n # # # f = flatten(yield_list) # print(list(f)) # # for i in f: # # print(i) # 用于展平列表元素. def yield_i(n): # print(n) try: for i1 in n: # 或者MyRange().[3, 4] # yield 'PP ' + str(i) # print(i1) # 3或4 # print(yield_i(i1)) for ii in yield_i(i1): # print(ii) yield ii except TypeError: yield n y = yield_i([1, 2, [3, 4], [[5]]]) print(list(y)) # for i in y: # print(i) # 上面内容只能应用于整型或者浮点型等不可迭代对象.如果在列表元素当中夹杂了字符串(可迭代对象),则会报错. # 上面内容有整型的报错而终止循环,但是字符串(可迭代对象)则不会终止循环. # 为了解决字符串等可迭代问题.我们可以加一个判断语句. def yield_ii(n): try: for i1 in n: if isinstance(i1, Iterable) and not isinstance(i1, list): # 判断i1是否是可迭代对象. yield '<可迭代对象> 类型:' + str(type(i1)) else: for ii in yield_ii(i1): yield ii except TypeError: yield n # 解决列表的展平问题,如果到不可迭代对象后,则会抛出错误,在用生成器返回,进行遍历,遍历后,再次进行生成器.返回生成器对象. y2 = yield_ii([1, 2, [3, 4], [[5]], 'String', [6], 'Str']) for i in y2: print(i) # 下面还有一些例子: from itertools import count, cycle, islice counter = count(start=13) print(next(counter)) print(counter.__next__()) print('*'*20) colors = cycle(['red', 'white', 'blue']) print(next(colors)) print(next(colors)) print(colors.__next__()) print(colors.__next__()) print('*'*20) limited = islice(colors, 0, 4) # print(dir(limited)) print(list(limited)) print('*'*20, '字典环节', '*'*20) brand = ['开始', '结束', '步长'] slogan = ['0', '5', '2'] print('联系:', brand[slogan.index('5')]) ZiDian = {'开始': '0', '结束': '5', '步长': '2'} print(ZiDian.keys()) # 键名. print(ZiDian.values()) # 值. print(ZiDian.items()) # 键值. # get()方法提供了更宽松的方式去访问字典项,当键不存在的时候,get()方法并不会报错,只是默默第返回一个None,表示啥都没找到. print(ZiDian.get('开始')) print(ZiDian.get('无', '木有')) # copy()方法是复制字典(全拷贝) brand1 = brand.copy() # 对于列表的复制copy. print(brand, id(brand)) print(brand1, id(brand1)) ZiDian1 = ZiDian.copy() # 对于字典的复制copy. print(ZiDian, id(ZiDian)) print(ZiDian1, id(ZiDian1)) ZiDian1['开始'] = '2' print(ZiDian, ZiDian1) # pop()是给定键d出对应的值,popitem()是随机d出一个项. print(ZiDian1.pop('步长')) print(ZiDian1) print(ZiDian1.popitem()) print(ZiDian1) # setdefault()方法与get()方法相似,但setdefault()在字典中找不到相应的键值时会自动添加. print(ZiDian1.setdefault('步长', '2')) print(ZiDian1) # update()方法可以更新字典. print(ZiDian1.update({'range': 'MyRange'})) print(ZiDian1) print(ZiDian1.update({'range': 'Range'})) print(ZiDian1) # clear()可清空一个字典. print(ZiDian1.clear()) print(ZiDian1) print('*'*20, '字典环节', '*'*20) print('*'*20, '集合环节', '*'*20) # 集合中的元素都是唯一的(集合会自动帮我们把重复的数据清理掉,集合是无序的,所以不能试图去索引集合中的某一个元素). num = {'1': '0'} print(type(num)) num1 = {'1', 1, '2', 2} print(type(num1)) # print(dir(num1)) print(num1) # 使用add()方法可以为集合添加元素,使用remove()方法可以删除集合中已知的元素. # 不可变集合(把元素给froze冰冻起来)(像元组一样不能随意地增加或删除集合中的元素). print('*'*20, '集合环节', '*'*20) import pickle # 可以非常容易地将列表、字典这类复杂的数据类型存储为文件.(转化成二进制). my_list = ['1', 5, '8', 9] print(pickle.dumps(my_list)) print(pickle.loads(b'\x80\x03]q\x00(X\x01\x00\x00\x001q\x01K\x05X\x01\x00\x00\x008q\x02K\te.')) # 注意:是字节类型. import easygui # EasyGui # print(easygui.msgbox('嗨,python')) # from easygui import * # print(msgbox('嗨, python')) # import easygui as f # print(f.msgbox('嗨,python')) # # 显示图片(注:图片需要为GIF格式,且存放在python.exe通目录). print('*'*20, '下面简单说下类', '*'*20) # 组合(将需要的类一起进行实例化并放入新的类中)这部分会在下面运行当中呈现出来效果. class Person(object): name = 'Person' # 类方法. __name = '私有Person' # 私有方法. def __init__(self, a, b): self.a = a self.b = b self.num = 5 self.flag = True print('Person __init__方法.') def pen(self): return self.__name # 从内部进行把私有名给输出来. def time(self): if self.flag: print('前 %s 小时' % self.a) self.flag = False else: print('后 %s 小时' % self.b) self.flag = True p = Person(12, 12) # 创建实例对象. print(id(p)) # p 和 p1 id不一样,一个类可以创建多个对象,这就是多态. p1 = Person(6, 6) print(id(p1)) print(p1.name) # print(p.__name) # 会报错,这是私有类方法,不能被输出. print(p1.pen()) # 可以通过访问类里面的方法进行内部的反馈. # print(p1._Person__name) # 在python中,只是把私有类方法改了下名字而已. class Person1(Person): # 应用于继承. pass print('*'*20, 'Person1环节') p2 = Person1(12, 12) p2.time() # 类的继承,子类可以应用父类方法. p2.time() print(p2.pen()) class Person2(Person): def __init__(self, c): # # 注意,如果子类有和父类一样的实例方法或类方法,会进行覆盖. self.c = c self.g = Person(12, 12) # 类似 f = Person(d)实例化得到对象. Person.__init__(self, 12, 12) # 第一种方法解决覆盖问题. # 第一种方法比如我修改了父类,后面也需要修改,造成不必要的麻烦.# 注意:此处 # self参数依旧是指向子类Person2的指针.通俗点,就是我把Person类的__init__方法指向了Person2,其实self是Person2的实例化对象. # 意思就是我把父类方法指向了Person2的实例化对象. # super(Person2, self).__init__(12, 12) # 第二种方法解决覆盖问题. def eat(self): if self.c == 12: print('当前时间 %s ' % self.c) self.c = 24 else: print('当前时间 %s ' % self.c) self.c = 12 print('*'*20, 'Person2环节') p3 = Person2(12) # 创建实例化对象. p3.eat() p3.eat() p3.time() # 注意,如果子类有和父类一样的实例方法或类方法,会进行覆盖. # 为了解决错误问题.需要导入父类的__init__方法. p3.time() # 也可以多继承,一个子类继承多个父类,就是你可以有多个爹,对吧?大致意思是class Person1(Person, Person2) # 多继承在应用方法上,有顺序之分 # 顺序的话基本不用你去算了,你只需要认定,第一个输入的参数就是第一个顺序. print('*'*20, '组合') per = Person2(12) # 进行实例化对象 print(per.g.num) # 以下例子可见,对实例对象c的count属性赋值后,就相当于覆盖了类对象C的count属性。如果没有赋值覆盖,那么引用的是类对象的count属性 p4 = Person(12, 12) # 创建实例化对象. p5 = Person(12, 12) p6 = Person(12, 12) print(id(p4), id(p5), id(p6)) print(p4.name, p5.name, p6.name) p6.name = 'Hello Person' print(p4.name, p5.name, p6.name) Person.name = '' print(p4.name, p5.name, p6.name) # 另外,如果属性的名字跟方法名相同,属性会覆盖方法. class C(object): def method(self): print('C:xxx') c = C() # 实例化对象. c.method() c.method = 1 print(c.method) # c.method() # 会报错,可见,方法x()已经被属性method给覆盖了. # 结论:不要试图在一个类里边定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展; # 用不同的词性命名,如属性名用名词、方法名用动词,并使用骆驼命名法等。 print('*'*20, '下面是绑定的概念.') # (python严格要求需要有实例才能被调用,即绑定概念) class B(object): def printB(): print('no zuo no die') B.printB() # 没有绑定实例对象时. b = B() # b.printB() # 出现错误原因是由于绑定机制,自动把b对象作为第一个参数传入. class A(object): name = '123' def printA(self): # 我方法绑定给实例对象. print('A') def printAA(self): self.printA() a = A() a.printA() a.printAA() # Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念. # issubclass(class, classinfo) 如果第一个参数(class)是第二个参数(classinfo)的一个子类,则返回True,否则返回False. print(issubclass(A, object)) # isinstance(object, classinfo) 如果第一个参数(object)是第二个参数(classinfo)的实例对象,则返回True,否则返回False. print(isinstance(a, A)) print(isinstance(a, object)) # hasattr(object, name) 用来测试一个对象里是否有指定的属性,第一个参数(object)是对象,第二个参数(name)是属性名(属性的字符串名字). print(hasattr(a, 'name')) # getattr(object, name[, default]) 返回对象指定的属性值,如果指定的属性不存在,则返回default(可选参数);若没有设置default参数,则抛出异常. print(getattr(a, 'age', '20')) # setattr(object, name, value) 可以设置对象中指定属性的值,如果指定的属性不存在,则会新建属性并赋值. setattr(a, 'age', '20') print(getattr(a, 'age')) # delattr(object, name) 用于删除对象中指定的属性,如果属性不存在,抛出异常。 print(delattr(a, 'age')) print(getattr(a, 'age', 50)) # property(fget=None, fset=None, fdel=None, doc=None) # 用来通过属性设置属性,第一个参数是获取属性的方法名,第二个参数是设置属性的方法名,第三个参数是删除属性的方法名. print('*'*20) class D(object): def __init__(self, size=10): self.size = size def getsize(self): return self.size def setsize(self, value): self.size = value def delsize(self): del self.size x = property(getsize, setsize, delsize) d = D() print(d.x) d.x = 12 print(d.x) del d.x # print(d.x) # 会报错. print('*'*20, '魔术方法') # 注:__init__()方法的返回值一定是None . # 其实,__new__()才是在一个对象实例化时候所调用的第一个方法,它的第一个参数是这个类(cla),而其他的参数会直接传递给__init__()方法. class CapStr(str): def __new__(cls, string): string = string.upper() # 大写 return str.__new__(cls, string) # 使用str的__new__方法,指向当前类,并把值提交给str. a = CapStr('hello world') print(a) # __del__(self) 当对象将要被销毁的时候,这个方法就会被调用。但要注意, # 并非del x就相当于调用x.__del__(),__del__()方法是当垃圾回收机制回收这个对象的时候才调用的。 class Poo1(object): def __init__(self): print('__init__被调用') # def __del__(self): # print('__del__被调用') k = Poo1() k1 = k k2 = k1 # print(id(k)) # 多指向标签. # print(id(k1)) # print(id(k2)) # del k # del k1 # del k2 print('*'*20) class NewInt(int): def __init__(self, value): self.value = value def __add__(self, other): # 先说参数,第一个self参数是当前实例化参数,而other是另外一个实例化参数. print(id(self), id(other)) # 进行比较id实例化a、b,应该和我猜想的一样吧,相当于我把实例化的b当成参数了. # print('add', self, other) # return int.__sub__(self, other) # 可以尝试着改成 int.__add__(self, other) # print(self.value, other.value) # 为了进一步验证我的想法. return int(self) + int(other) # #将self与other强制转换为整型,所以不会出现两个对象相加触发__add__()方法 def __sub__(self, other): # print('sub', self, other) # return int.__add__(self, other) # 和上面一样进行修改. return int(self) - int(other) # def __str__(self): # return self.value a = NewInt(3) b = NewInt(5) c = NewInt(1) # print(a, b) # print(a.value) # print(b.value) # print(type(a), type(b)) # 先说下相加和相减的前提是类型要一样,从这里可以看出,出自同一个类. print(id(a), id(b)) # print(a) # out -> 3 # print(b) # out -> 5 print(a + b) # 两个对象相加,触发 __add__(self,other)方法.# 顺序>>实例a -> 触发add方法(+) -> 实例b. + 返回 - 的效果. # a + b运行模式应该是,b 进入了 a中,所以当前self是a,所以b相当于传入进去的参数,但是a和b都是同一个类.所以a能用的b也能用. print(a - b) print(a + b + c) class NenInt(object): def __init__(self, value): self.value = value # print('__init__ %s ' % self.value) # 体现是否创建了实例化对象. def __add__(self, other): # NenInt(f'{self.value}{other.value}') 相当于一个实例化对象.NenInt('aaaAAA'). # print('add', self, other) return NenInt(f'{self.value}{other.value}') # 运行顺序 -> 先运行Nen + Nen1,运行完之后(Nen + Nen1) + Nen2. def __str__(self): # 对实例化对象进行返回self.value. return self.value NenInt('ooo') Nen = NenInt('aaa') Nen1 = NenInt('AAA') Nen2 = NenInt('bbb') # Nen3 = NenInt('BBB') # 用于验证. # print(Nen) print(Nen + Nen1 + Nen2) # 可以把__str__方法注释掉,看下前后效果. class Vector(object): def __init__(self, box, eye): self.box = box self.eye = eye def __add__(self, other): return Vector(self.box + self.eye + other.box, self.eye + other.box + other.eye) def __str__(self): return 'Vector ( %s , %s )' % (self.box, self.eye) v = Vector(10, 2) v1 = Vector(20, -5) print(v + v1) print('*'*20) # 这里a是加数,b是被加数,如果a对象的__add__()方法没有实现或者不支持相应的 *** 作,那么python就会自动调用b的__radd__()方法 class NInt(int): def __init__(self, q): self.q = q def __radd__(self, other): # print(self.q) # 用于观看self实例化对象是谁. return int.__sub__(self, other) # 调用减. a = NInt(5) b = NInt(3) print(a + b) # 由于a对象默认有__add__()方法,所以b的__radd__()没有执行. print(3 + b) # 由于3无__add__()方法,所以执行b的反运算__radd__(self,other)方法,其中self是b对象. print(b + 3) print('*'*20) # class MyClass(object): # def __add__(self, other): # return self + other # # # def __str__(self): # # return self # # # Cla = MyClass() # Cla1 = MyClass() # print(Cla + Cla1) from datetime import datetime # 定制一个计时器类. # class MyTimer(object): # def __init__(self, total=0): # self.begin = 0 # 时间始. # self.end = 0 # 时间末. # self.total = total # # def __add__(self, other): # # return '相加 %s 秒' % round(float(self.total) + float(other.total), 1) # 本身就是浮点数. # return MyTimer(self.total + other.total) # # def __str__(self): # 用于解决实例对象的返回的问题. # return str(self.total) # # def start(self): # 启动计数. # print('启动计时器...') # self.begin = datetime.now() # 标记起始时间. # return self.begin # # def stop(self): # 停止计时. # print('终止计时器!!!') # self.end = datetime.now() # self.total = round(self.end.timestamp() - self.begin.timestamp(), 1) # print('总共运行了 %s 秒' % self.total) # return self.total # # def cycle(self): # name = input('start/stop:').strip() # while True: # if name == 'start': # self.start() # name = input('stop:').strip() # if name == 'stop': # pass # elif name == '0': # break # else: # print('*' * 20, '请按照规则:start/stop或者退出(0)', '*' * 20) # elif name == 'stop': # self.stop() # break # # elif self.name == '+': # 本来也可以在这里加,但是针对性太强,反而没有灵活性的去相加. # # pass # else: # break # # # time = MyTimer() # # print(time.start()) # # print(time.stop()) # time1 = MyTimer() # time2 = MyTimer() # time.cycle() # time1.cycle() # time2.cycle() # # time2 = MyTimer() # print('相加', time + time1 + time2, '秒') # # print(time + time1) # class MyTimer(int): # def __init__(self, total=0): # self.begin = 0 # 时间始. # self.end = 0 # 时间末. # self.total = total # # def __add__(self, other): # # print(type(self), type(other)) # # # print(self, other) # # print(self.total, other.total) # # print(type(self), type(other)) # print(self, other, type(self), type(other), type(int(self)), type(int(other))) # return int(self) + int(other) # # return float(self) + float(other) # 本身就是浮点数. # # return '相加 %s 秒' % MyTimer(self.total) # # def __radd__(self, other): # print('__radd__') # return int.__add__(self, other) # # # def __str__(self): # 用于解决实例对象的返回的问题. # # return str(self.total) # # def start(self): # 启动计数. # print('启动计时器...') # self.begin = datetime.now() # 标记起始时间. # return self.begin # # def stop(self): # 停止计时. # print('终止计时器!!!') # self.end = datetime.now() # self.total = round(self.end.timestamp() - self.begin.timestamp(), 1) # print('总共运行了 %s 秒' % self.total) # # return self # # def cycle(self): # name = input('start/stop:').strip() # while True: # if name == 'start': # self.start() # name = input('stop:').strip() # if name == 'stop': # pass # elif name == '0': # break # else: # print('*' * 20, '请按照规则:start/stop或者退出(0)', '*' * 20) # elif name == 'stop': # self.stop() # break # # elif self.name == '+': # 本来也可以在这里加,但是针对性太强,反而没有灵活性的去相加. # # pass # else: # break # # # time = MyTimer(5) # # print(time.start()) # # print(time.stop()) # time1 = MyTimer(2) # time2 = MyTimer(1) # time3 = MyTimer(1) # # time.cycle() # # time1.cycle() # # time2.cycle() # print(time + time1 + time2 + time3) # 从上面种种表现可知,我是先触发__add__然后再触发了__radd__. # # print(time + time1) # print(time2) # print(type(time2)) # class MyTimer(object): # def __init__(self, total=0): # self.begin = 0 # 时间始. # self.end = 0 # 时间末. # self.total = total # # def __add__(self, other): # # print(self, other, type(self), type(other)) # # print('__add__') # try: # return str(self.total + other.total) # except AttributeError: # return self.total + other # # def __radd__(self, other): # # print('__radd__') # return MyTimer.__add__(self, float(other)) # # # def __str__(self): # 用于解决实例对象的返回的问题. # # return str(self.total) # # def start(self): # 启动计数. # print('启动计时器...') # self.begin = datetime.now() # 标记起始时间. # return self.begin # # def stop(self): # 停止计时. # print('终止计时器!!!') # self.end = datetime.now() # self.total = round(self.end.timestamp() - self.begin.timestamp(), 1) # print('总共运行了 %s 秒' % self.total) # # return self # # def cycle(self): # name = input('start/stop:').strip() # while True: # if name == 'start': # self.start() # name = input('stop:').strip() # if name == 'stop': # pass # elif name == '0': # break # else: # print('*' * 20, '请按照规则:start/stop或者退出(0)', '*' * 20) # elif name == 'stop': # self.stop() # break # else: # break # # # time = MyTimer() # # print(time.start()) # # print(time.stop()) # time1 = MyTimer() # time2 = MyTimer() # # time3 = MyTimer() # time.cycle() # time1.cycle() # time2.cycle() # # time3.cycle() # print('总共', time + time1 + time2, '秒') # 从上面种种表现可知,我是先触发__add__然后再触发了__radd__. # # print(time + time1) # # print(time2) # # print(type(time2)) # class MyTimer(object): # 之后再尝试了. # def __init__(self): # self.date = ['年', '月', '日', '小时', '分钟', '秒'] # self.begin = 0 # self.end = 0 # # def __add__(self, other): # return None # # def start(self): # if not self.stop: # print('*'*20) class IndexAtt(object): # x = 1 def __getattribute__(self, item): # –定义当该类的属性被访问时的行为. print('__getattribute__') return super(IndexAtt, self).__getattribute__(item) # 根类__getattribute__应该返回给根类的__getattr__. # return IndexAtt.__getattr__(self, item) def __getattr__(self, item): # –定义当用户试图获取一个不存在的属性时的行为. print('__getattr__') return ' %s 类方法不存在.' % item def __delattr__(self, item): # –定义当一个属性被删除时的行为. print('__delattr__') super(IndexAtt, self).__delattr__(item) def __setattr__(self, key, value): # –定义当一个属性被设置时的行为. print('__setattr__') super(IndexAtt, self).__setattr__(key, value) def __str__(self): return 'I' I = IndexAtt() print(I.x) print('*'*20) I.x = 2 print('*'*20) print(I.x) print('*'*20) del I.x print('*'*20) print(I.x) print('*'*20) class Rectangle(object): def __init__(self, width, height): self.width = width # 宽. self.height = height # 高. def __setattr__(self, key, value): if key == 'square': self.width = value self.height = value else: self.__dict__[key] = value def getarea(self): return self.width * self.height r = Rectangle(5, 4) print(r.getarea()) r.square = 5 print(r.getarea()) r.p = 4 print(r.__dict__) print('*'*20) # 描述符. class MyDescriptor(object): def __init__(self): self.a1 = 'aa1' print('MyDescriptor') def __get__(self, instance, owner): print('get', self, instance, owner) return self def __set__(self, instance, value): print('set', self, instance, value) def __delete__(self, instance): print('del', self, instance) def __getattribute__(self, item): # print(self, item) # return '触发1 %s ' % item return super(MyDescriptor, self).__getattribute__(item) class Test(object): x = MyDescriptor() # 取MyDescriptor类的实例指派给Test类的属性x. # 相当于创建实例对象. def __init__(self): self.a2 = 'a2' self.x = '实例化对象' # 类似Test实例化对象对x类方法进行设置. print('Test') # def __getattribute__(self, item): # 刻属性可以让描述器失效. # return '触发2 %s ' % item # return super(Test, self).__getattribute__(item) test = Test() test.x Test.x print(Test.x.a1) # print(test.x.a1) # print(test.x) # 有顺序之分.__getattribute__ -> 数据描述符 -> 实例对象的字典 -> 类的字典 -> 非数据描述符 -> 父类的字典 -> getattr(). # 所以呐,就先注释掉__set__、__get__、__delete__其中两个使之变成非数据描述符. # test.x = '可口' # del test.x
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)