基于网络课程《Python全栈开发专题》 记录笔记,请支持正版课程。
构造方法
class Person:
def __init__(self, name='Bill'):
print('构造方法已经被调用')
self.name = name
def getName(self):
return self.name
def setName(self, name):
self.name = name
p1 = Person()
print(p1.getName())
p2 = Person(name='二狗')
print(p2.getName())
重写普通方法和构造方法
super().__init__()
调用父类构造器
'''
在Python中重写只看方法名,不看参数
'''
class Bird:
def __init__(self):
print('Bird构造器')
self.hungry = True
def eat(self):
if self.hungry:
print('吃包子……………………………………')
self.hungry = False
else:
print('吃过了')
class SongBird(Bird):
def __init__(self):
super().__init__()
print('SongBird构造器')
self.sound = '唱歌'
def sing(self):
print(self.sound)
def eat(self, thing):
print('吃', thing)
b = Bird()
b.eat()
b.eat()
s = SongBird()
s.sing()
s.sing()
s.eat('鸡腿')
super(),调用其他类的构造器
class MyClass1:
def __init__(self):
print('MyClass1')
class MyClass2(MyClass1):
def __init__(self):
print('MyClass2')
class MyClass3(MyClass2):
def __init__(self):
# super().__init__()
# super(MyClass3, self).__init__() # 这种写法和上面是等效的
super(MyClass2, self).__init__() # 调用MyClass2的父类构造器
print('MyClass3')
m = MyClass3()
自定义序列
-
__init__
,构造方法,你懂的 -
__getitem__
,获取value -
__setitem__
,设置键值 -
__delitem__
,删除值 -
__len__
,长度
class FactorialDict():
def __init__(self):
self.numDict = {}
def factorial(self, n):
if n == 0 or n == 1:
return 1
else:
return n * self.factorial(n - 1)
def __getitem__(self, key):
print('__getitem__方法被调用了, key = {}'.format(key))
if key in self.numDict:
return self.factorial(self.numDict[key])
else:
return 0
def __setitem__(self, key, value):
print('__setitem__方法:key = {}'.format(key))
self.numDict[key] = int(value)
def __delitem__(self, key):
print('__delitem__方法:key = {}'.format(key))
del self.numDict[key]
def __len__(self):
print('__len__方法:')
return len(self.numDict)
d = FactorialDict()
d['4!'] = 4
d['7!'] = '7'
d['12!'] = 12
print('4! = {}'.format(d['4!']))
print('长度:{}'.format(len(d)))
del d['7!']
从内建列表、字典和字符串继承
- 继承内建类list。
__getitem__()
方法
class ConterList(list):
def __init__(self, *args):
super().__init__(*args)
self.counter = 0
def __getitem__(self, index):
self.counter += 1
return super().__getitem__(index)
c = ConterList(range(10))
print(c)
c.reverse()
print(c)
del c[3]
print(c.counter)
print(c[1] * c[3])
print(c.counter)
- 继承内建类dict
class CounterDict(dict):
def __init__(self, *args):
super().__init__(*args)
self.counter = 0
def __getitem__(self, key):
self.counter += 1
return dict.__getitem__(self, key)
d = CounterDict({'name': '二狗'})
print(d['name'])
print(d.get('age'))
# print(d['age']) # 如果使用 [] ,键不存在时会报错
print(d.counter)
- 继承内建类str
class MultiString(str):
def __new__(self, *args, sep=' '):
s = ''
for arg in args:
s += arg + sep # 把 arg 和分隔符拼接起来
# 如果sep不为空,需要把最后一个sep截取掉
index = -len(sep)
if index == 0:
index = len(s)
return super().__new__(self, s[:index])
def __init__(self, *args, sep=' '):
pass
s1 = MultiString('a', 'b', 'c')
print(s1)
s2 = MultiString('a', 'b', 'c', sep = '')
print(s2)
s3 = MultiString('a', 'b', 'c', sep = '*')
print(s3)
属性与property() 函数
class Rectangle:
def __init__(self):
self.left = 0
self.top = 0
def setLeft(self, left):
self.left = left
def setPosition(self, position):
print('setPosition 方法')
self.left, self.top = position # 用元组直接赋多个值
def getPosition(self):
print('getPosition 方法')
return self.left, self.top # 直接返回一个元组,java程序员看哭了
def deletePosition(self):
print('position 属性已经被删除')
self.left = 0
self.top = 0
# 用 property() 函数绑定get/set/del方法 !!!
position = property(getPosition, setPosition, deletePosition)
r = Rectangle()
r.left = 100
print(r.left) # 100
r.setPosition([400, 500])
print(r.getPosition())
'''
setPosition 方法
getPosition 方法
(400, 500)
'''
r.position = 123, 456
print(r.position)
'''
setPosition 方法
getPosition 方法
(123, 456)
'''
del r.position
print(r.position)
'''
position 属性已经被删除
getPosition 方法
(0, 0)
'''
监控对象中的所有属性
'''
__getattr__(): 用来监控所有属性的读操作
__setattr__(): 用来监控所有属性的写操作
__delattr__(): 用来监控所有属性的删除操作
'''
class Rectangle:
def __init__(self):
self.width = 0
self.height = 0
self.left = 0
self.top = 0
def __setattr__(self, name, value):
print('{} 被设置, 新的值为: {} '.format(name, value))
if name == 'size':
self.width, self.height = value
elif name == 'position':
self.left, self.top = value
else:
self.__dict__[name] = value
def __getattr__(self, name):
print('{} 被获取'.format(name))
if name == 'size':
return self.width, self.height
elif name == 'position':
return self.left, self.top
def __delattr__(self, name):
print('{} 属性将被删除'.format(name))
if name == 'size':
self.width, self.height = 0, 0
elif name == 'position':
self.left, self.top = 0, 0
r = Rectangle()
r.size = 100, 200
'''
width 被设置, 新的值为: 0
height 被设置, 新的值为: 0
left 被设置, 新的值为: 0
top 被设置, 新的值为: 0
size 被设置, 新的值为: (100, 200)
width 被设置, 新的值为: 100
height 被设置, 新的值为: 200
'''
print(r.size)
print(r.position)
'''
size 被获取
(100, 200)
position 被获取
(0, 0)
'''
del r.size, r.position
print(r.size, r.position)
'''
size 属性将被删除
width 被设置, 新的值为: 0
height 被设置, 新的值为: 0
position 属性将被删除
left 被设置, 新的值为: 0
top 被设置, 新的值为: 0
size 被获取
position 被获取
(0, 0) (0, 0)
'''
class MyClass:
def __setattr__(self, name, value):
if name == 'value':
if value > 0:
self.__dict__[name] = value
else:
print('{}的属性值必须大于0!'.format(name))
else:
self.__dict__[name] = value
c = MyClass()
c.value = 20
print(c.value)
c.value = -1
print(c.value) # 设置不成功,还是20
静态方法和类方法
'''
在实例方法中,可以调用静态方法和类方法,反之不成立!
'''
class MyClass:
name = '二狗'
def __init__(self):
print('MyClass的构造器')
self.value = 20
# 定义静态方法
@staticmethod
def run():
print(MyClass.name, 'MyClass的静态方法被调用')
# 定义类方法
@classmethod
def do(cls):
print(cls) #
print('[{}]'.format(cls.name))
cls.run() # 类方法中可以调用静态方法
def do1(self):
print(self) # <__main__.MyClass object at 0x0000022BED0640B8>
print(self.value)
print('< {} >'.format(self.name))
self.do() # 实例方法中可以调用静态方法和类方法
self.run()
# 调用静态方法
MyClass.run()
c = MyClass()
c.do()
c.do1()
c.run()
MyClass.do()
自定义可迭代的类
__iter__()
, __next()__
class RightTriangle:
def __init__(self):
self.n = 0
def __iter__(self):
return self
def __next__(self):
self.n += 1
return '*' * (2 * self.n -1)
rt = RightTriangle()
for e in rt:
if len(e) > 20:
break
print(e)
自定义可迭代类版本的斐波那契数列
class Fibonacci:
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
result = self.a
self.a, self.b = self.b, self.a + self.b
return result
fibs = Fibonacci()
for fib in fibs:
print(fib, end=' ')
if fib > 1000: break
将迭代器转换为列表
设置条件,抛出StopIteration异常,中断迭代!
class Fibonacci:
def __init__(self):
self.a = 0
self.b = 1
def __iter__(self):
return self
def __next__(self):
result = self.a
self.a, self.b = self.b, self.a + self.b
# 设置条件,抛出StopIteration异常,中断迭代!
if result > 1000: raise StopIteration
return result
fibs = Fibonacci()
print(list(fibs))
生成器(Generator)
yield
关键字
from sqlalchemy.util.compat import nested
def myGenerator():
numList = [1, 2, 3, 4, 5, 6, 7, 8]
for num in numList:
yield num
for num in myGenerator():
print(num, end = ' ')
print()
#######################################
nestedList = [[1, 2, 3], [4, 5, 6], [7, 8]]
def enumList(nestedList):
for subList in nestedList:
for element in subList:
yield element
for num in enumList(nestedList):
print(num, end = ' ')
print()
print(list(enumList(nestedList)))
另一个例子
nestedList = [[1, 2, 3], [4, 5], 20, [6, 7], [8, 9, 10]]
def enumList(nestedList):
try:
for subList in nestedList:
for element in enumList(subList):
yield element
except TypeError:
# 本例中,循环到20时会抛出TypeError, 此时的nestedList就是20
yield nestedList
for num in enumList(nestedList):
print(num, end = ' ')
防止字符串也被迭代
nestedList = [[1, 2, 3], [4, 5], 'abc', [6, 7], [8, 9, 10]]
def enumList(nestedList):
try:
# python 里面,字符串和数字不能直接相加,如果是字符串,会报错。
# 这个步骤防止字符串被迭代
try:nestedList + ''
except:
pass
else:
raise TypeError
for subList in nestedList:
for element in enumList(subList):
yield element
except TypeError:
yield nestedList
for num in enumList(nestedList):
print(num, end = ' ')
练习1:用类的迭代,做一个阶乘计算器
class Factorial:
def __init__(self):
self.result = 1 # 当前的阶乘结果
self.n = 0 # 迭代的次数
def __iter__(self):
return self
def __next__(self):
self.n += 1
# print('debug >>>>> {} * {}'.format(self.result, self.n))
self.result = self.result * self.n
return self.n, self.result
factorial = Factorial()
print('阶乘计算器')
for n, result in factorial:
print('{}! = {}'.format(n, result))
if n >= 10: break
练习2:阶乘计算器2.0
加入StopIteration,可以直接用list()
方法返回列表了。
class Factorial:
def __init__(self, max = 10):
self.result = 1 # 当前的阶乘结果
self.n = 0 # 迭代的次数
self.max = max # 最大迭代到几的阶乘
def __iter__(self):
return self
def __next__(self):
self.n += 1
# print('debug >>>>> {} * {}'.format(self.result, self.n))
self.result = self.result * self.n
if self.n > self.max:
raise StopIteration
return self.n, self.result
def reset(self):
self.__init__();
factorial = Factorial()
print(list(factorial))
# 阶乘计算器使用之后,需要调用reset()方法,清空,否则就不能迭代2
print(list(factorial))
factorial.reset()
print(list(factorial))
f = Factorial(max = 5)
print(list(f))
练习3:Fibonacci数列
def fibonacci(n):
'''
生成器
'''
if n < 1: raise Exception('请输入一个大于0的正整数')
a, b = 1, 1 # a,前两项;b, 前一项
for i in range(n):
i += 1
if i > n: raise StopIteration # 终止
if i == 1 or i == 2:
yield 1 # 前两项都是1
else:
result = a + b
a, b = b, result
yield result
for f in fibonacci(10):
print(f, end = ' ')
print()
class Fibonacci:
'''
迭代类
'''
def __init__(self, max = 10):
self.a, self.b = 1, 1
self.max = max # 最大迭代到数列的第几个
self.counter = 0 # 第几次迭代
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter > self.max: raise StopIteration
if self.counter == 1 or self.counter == 2:
return 1
else:
result = self.a + self.b
self.a, self.b = self.b, result
return result
f = Fibonacci()
print(list(f))
def fibonaccr2(n):
'''
用迭代类做一个生成器
'''
fibs = Fibonacci(max = n)
for fib in fibs:
yield fib
for f in fibonaccr2(20):
print(f, end = ' ')