python学习笔记(二)
2019-06-20 本文已影响104人
dev_winner
面向对象程序设计
-
self
:类的方法与普通的函数只有一个特别的区别——必须提供一个额外的第一个参数名称:self
,调用时不必给这个参数赋值。 - Python中的
self
等价于C++中的self指针
和Java、C#中的this
。 - 提示警告⚠:This inspection detects any methods which may safely be made static.
- 原因:该方法不涉及对该类属性的操作,编译器建议声明为
@staticmethod
,这是面向对象思想体现!!!
-
__init__
方法在类的一个对象被建立时,马上运行。
class Person:
def __init__(self, name): # 自定义类的构造函数
self.name = name
# @staticmethod
def say_love(self):
print(self.name, 'I love you!')
def main():
p = Person("李淑楠")
p.say_love()
if __name__ == '__main__':
main()
# 李淑楠 I love you!
-
类的变量(static)
由一个类的所有对象(实例)共享使用;对象的变量
由类的每个对象/实例拥有。当对象不再被使用
时,__del__
方法才执行,但很难保证这个方法究竟在什么时候运行,若想要指明它的运行,就得使用del
语句。
class Person:
count_num = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
def __init__(self, name): # 自定义构造函数
self.name = name
self.__class__.count_num += 1 # 先访问到类本身,然后再访问自身的共享成员变量
print("初始化参数", self.__class__.count_num)
# @staticmethod
def say_love(self):
print(self.name, 'I love you!')
def __del__(self):
self.__class__.count_num -= 1
print("释放", self.__class__.count_num)
def main():
p1 = Person("li")
p1.say_love()
p2 = Person('zhang')
p2.say_love()
print("初始化、调用已经完事了")
del p1 # 一般需要手动释放类的内存
del p2
if __name__ == '__main__':
main()
运行结果
- Python中所有的类成员(包括数据成员)都是
公共(public)
的。私有变量的标志:双下划线前缀
,如:__count_num
。 - 继承:代码的重用。
class Person(object):
count_num = 0 # 所有的实例都共享此变量,即不单独为每个实例分配
def __init__(self, name): # 自定义构造函数
self.name = name
self.__class__.count_num += 1 # 先访问到类本身,然后再访问自身的共享成员变量
print("初始化参数,当前共有", self.__class__.count_num, "个类实例")
print("当前调用的是父类")
# @staticmethod
def say_love(self):
print(self.name, 'I love you!')
def __del__(self):
self.__class__.count_num -= 1
print("释放资源,当前类实例个数为", self.__class__.count_num)
class Zhang(Person): # 继承父类Person
def __init__(self, name): # 定义自己的构造方法
Person.__init__(self, name) # 先调用父类的构造方法,法一
# super(Zhang, self).__init__(name) # 法二
self.name = name
print("当前调用的是子类")
# @staticmethod
def listen_to_music(self):
Person.say_love(self) # 子类调用父类的方法
print("当前用户名为\'", self.name, "\'正在听音乐")
print("当前共有", self.count_num, "个类实例")
def main():
p1 = Zhang('李淑楠')
p1.listen_to_music()
if __name__ == '__main__':
main()
- Python不会自动调用
基类(父类)
的constructor构造方法,必须亲自专门调用它。 - 重写:Python总是首先查找对应类型的方法,若它不能在导出类中找到对应的方法,它才开始到基本类中逐个查找。
- python没有重载,只有重写。
- 多重继承
输入/输出
def op_file(file_name, open_mode, flag):
if flag == 1: # 读文件操作
with open(file_name, open_mode, encoding='UTF-8') as f1: # 自动调用file.close()方法,无需使用try...finally来实现
cnt = 0
for _line in f1.readlines(): # 读取每一行的内容
cnt += 1
print(_line.strip()) # 把末尾的'\n'删掉,print输出会在末尾加一个换行'\n'
# while True:
# text_new = f1.readline()
# if len(text_new) == 0:
# break
# cnt += 1
# print(text_new)
print("一共读取了", cnt, "次")
else: # 写文件操作
with open(file_name, open_mode, encoding='UTF-8') as f2:
f2.write("李淑楠,我喜欢你!李淑楠,我喜欢你!李淑楠,我喜欢你!\n")
def main(f_name):
# op_file(f_name, 'a', 2) # 追加模式
op_file(f_name, 'r', 1) # 只读模式
if __name__ == '__main__':
file_n = 'test04.txt'
main(file_n)
- python的pickle模块实现了基本的数据序列和反序列化。
- 通过pickle模块的
序列化操作
我们能够将程序中运行的对象信息保存到文件中去,永久存储
。 - 通过pickle模块的
反序列化操作
,我们能够从文件中创建上一次程序保存的对象
。
import pickle
def main():
# 定义一个字典
dict1 = dict(name="张三", age=12)
# dict1 = {'name': "张三", 'age': 12}
# print(dict1)
with open('data05.txt', 'wb') as fw: # 存储方式默认是二进制方式
pickle.dump(dict1, fw) # 序列化对象
with open('data05.txt', 'rb') as fr:
data = pickle.load(fr) # 反序列化对象
print(data)
if __name__ == '__main__':
main()
异常
- 使用
try..except语句
来处理异常。
def main():
try:
print(3 / 0)
except ZeroDivisionError as e:
print("error:", e)
finally:
print("finally...")
if __name__ == '__main__':
main()
# error: division by zero
# finally...
- 检验try...finally语句:在程序运行的时候,按
ctrl-c
中断/取消程序,可以发现finally从句最后总是被执行!
import time
def main():
try:
fr = open("test04.txt", 'r', encoding='UTF-8')
while True:
line1 = fr.readline()
if len(line1) == 0:
break
time.sleep(2) # 暂停2s
print(line1)
finally:
fr.close()
print("finally...")
if __name__ == '__main__':
main()
finally从句最后必然被执行
- 列表综合:若使用的是
**前缀
,多余的参数会被认为是一个字典的键/值对;若使用的是*前缀
, 多余的参数都会作为一个元组存储在args。
def op_f(num, *args): # 多余的参数都会作为一个元组存储在args中
print(num, args)
for x in args:
print(x)
def main():
# list1 = [2 * i for i in range(1, 5) if 2 * i > 3]
# print(list1)
op_f(1, 2, 3, 'zhang', 'li')
if __name__ == '__main__':
main()
# [4, 6, 8]
# 1 (2, 3, 'zhang', 'li')
# 2
# 3
# zhang
# li
- lambda匿名函数
-
exec
语句用来执行储存
在字符串或文件中的Python语句 -
eval
语句用来计算存储
在字符串中的有效Python表达式
def gt(x1):
return lambda y: y * x1 # y是匿名函数的参数
def gf():
return lambda: True # 无参匿名函数
def main():
p = gt(2)
print(p('word_'))
print(p(5))
t = gf()
print(t())
max_v = lambda x, y: x if x > y else y # 取最大值
print(max_v(3, 222))
exec('print(max_v(3, 222))')
ques = '2 * (1 + 3)'
print(eval(ques))
if __name__ == '__main__':
main()
# word_word_
# 10
# True
# 222
# 222
# 8
-
抛AssertionError异常assert
语句用来声明某个条件是真的,当assert语句失败的时候,会引发一个AssertionError
异常;否则没有任何输出!
-
repr
函数用来取得对象的规范字符串表示!