《Python编程,从入门到实践》- 04 函数&类&文件&异常
函数
def 开头+方法名+(参数)
# 函数 def print_hello(name) : name = "Alice" temp = "temp" print("Hello," + name) print(num) name = "Tom" num = 15 # 这个定义是全局的 print_hello(name) # 如果上面两行互换是会报错的,仔细想想是为什么 print(name) # 打印是Tom所以说并没有被改变 # print(temp) 函数里定义的是局部的
说到函数就不的不说传参的问题。
形参和实参的问题,值传递的问题等等。
简单来说,形参就是个名字不存在具体内容,而实参是存在的。
上面函数参数里的name就是个形参,而下面调用时传入的这个name是实参。
不可变对象传的都是值,而可变对象传的是引用,这就是上面那个为什么没有变。
来看个其他的例子:
class person: def __init__(self, name, address): self.name = name self.address = address def __repr__(self): # 以后再说明这个函数 return '(name:' + self.name + ', address:' + self.address + ')' def change(person): person.address = 'tokyo' ps = person('alcice', 'los') change(ps) print(ps.address) # tokyo
这里就发生了改变。
关于函数的其他一些问题,我就用代码展示了:
def sum_2(a = 5, b = 0): # 传两个参数注意顺序,赋了默认值,注意一点,如果只传一个参数,默认是第一个位置 sums = a + b return sums # 不存在返回类型这种说法,应该是任意都可以 print(sum_2(1, 2)) # 3 # sum_2(,2) 这个写法是不可以的 def build_list(name, address): list = {"name": name, "address": address} return list print(build_list("Tome", "China")) # {'name': 'Tome', 'address': 'China'} def change_ele(list): # 列表的内容是会全局改变的,而简单变量不会 list[0] = 2 element = 2 # change_ele(list[:]) 这样子相当于做了个切片不会改变原来的那个list,而是新建了一个 element = 0 nums = [0,0,0,0] change_ele(nums) print(nums) # [2, 0, 0, 0] print(element) # 0 def make_tuple(*ele): # 这个地方相当于生成了一个元祖,用*可以输入多个 list = ele return list def test_make(*ele) : list = [a for a in ele] # 乖孩子们不要学我的命名方式 return list print("test_make:", test_make(1, 2, 3, 5)) # test_make: [1, 2, 3, 5],生成了列表 print(make_tuple(1, 2, 3, 45)) # 打印(1, 2, 3, 45) 它相当于一个元祖 def make_dic(**ele): # **相当于一个 字典 res = ele return res print(make_dic(name = "Tom", address = "China")) # {'name': 'Tom', 'address': 'China'}
函数部分就简单说到这吧,在写《Fluent Python》笔记的时候会说一些高阶函数之类的。
类
class+类名+(继承你想继承的类,不想继承就不用写):
#类 class Dog(): def __init__(self, name, age): # self. 相当于是这个类的属性,init相当于构造函数 self.name = name self.age = age self.others = "nothing" def sit(self): print(self.name + " is now sitting") def roll_over(self): print(self.name + " rolled over!") def get_age(self): return self.age def set_age(self, age): self.age = age if __name__ == '__main__': dog1 = Dog("alice", 12) # 创建对象,其实是调用了Dog 的init方法 dog2 = Dog("tom", 12) dog1.sit() dog2.roll_over() # 修改属性值 dog1.age = 10 # 直接修改 print("dog's age: " + str(dog1.age)) dog1.set_age(5) # 写get set方法 print("dog's age: " + str(dog1.age))
这个代码里我写了get和set方法,因为这个代码是我一开始学的时候写的,这个是我写Java留下的习惯。
Java里比较注重封装的思想,Python里的私有化是前面加双下线,但是很多人都不推荐用这种写法,有的人说用一个下线来表示私有。
简单说一下Python可单继承也可多继承,不支持重载,可以采用装饰器之类的方式伪重载。
继承:
# 继承 class Animal: def __init__(self, age): self.age = age def say_hello(self): print("hello Animal") class Human(Animal): def __init__(self, age, name): super().__init__(age) self.name = name def say_hello(self): print("hello", self.name) if __name__ == '__main__': person1 = Human(18, "Tom") print(person1.name, person1.age) # Tom 18 person1.say_hello() # hello Tom
支持重写。
python标准库是一组模块,安装python的就包含进来了,例如collections就是自带的一个集合包。当然你也外部用pip指令导入一些其他包,例如NumPy,OpenCV等等
文件
filePath = 'C:/Users/riarty/Desktop/test.txt' # 关于斜杠,书上说windows下是反斜杠,但我这里使用反斜杠是转义,会报错,还是只能用斜杠 # filePath = 'C:\\Users\\riarty\\Desktop\\test.txt' # win 下应该是使用双反斜杠 with open(filePath) as file_object: # 路径方式和其他语言类似,不指定默认此文件夹下 contents = file_object.read() # read() 读取内容,但会多出来一个空行,如果要删除则使用 rstrip print(contents.rstrip()) # with 在不需要访问文件后将其关闭 ,自动关闭,不需要显示的close() # 逐行读取 filePath2 = 'pi_digits.txt' with open(filePath2) as file_object: for line in file_object: print(line) # 每行都有一个默认的换行符,按行打印的时候,最后这个换行符会被打出来, # print是默认换行的,所以就出现多出来一行空白的情况 # 注意一次打开中如读取了一边,那么再去读取时需要注意,就类似于 流 一样 下面这个例子就是拿不到东西的 lines = file_object.readlines() # 可以直接拿到行的列表 print("lines: ", lines) with open(filePath2) as file_object: lines = file_object.readlines() pi = "" for line in lines : pi += line.strip() print(pi) print(pi.__len__()) # # 写入 # with open(filePath, 'a') as file_object: # 'w' 写入模式(注意会清除原来的内容) 如果不加的话,默认是 'r' 只读,其他还有 # # 'a' 附加模式(尾添加,不会自动换行) 'r+' 读写模式 # file_object.write("\nditto")
异常
# 异常 # print(5/0) # Traceback (most recent call last): # File "D:/project/venv/book/demo-10.2.py", line 2, in <module> # print(5/0) # ZeroDivisionError: division by zero a = 1 # int(input("first: ")) b = 1 # int(input("second: ")) try: answer = a/b except ZeroDivisionError : # 执行如果出异常 print("error") else: # 执行如果没出异常 print(answer)
json存储
numbers = [2, 3, 5, 7, 11, 13] filename = 'numbers.json' with open(filename, 'w') as f_obj: # 若文件不存在,'w' 会自动创建 json.dump(numbers, f_obj) # json.load 是读取json文件
结语:
关于《Python编程,从入门到实践》这本书的笔记我就写到这里了,这本书后续还有几个章节,我简单说一下内容,有个实战小游戏,还有数据可视化以及python-web,主要是用了Django框架。
我主要是搞Java的,做web我肯定是用Java来做。整个书我就用了四篇blog就写完了,这本书是面向纯初学者的,我在写blog的时候把很多话都省了,比方说,为什么要用函数,为什么要用这个或者那个。以及一些对数据结构的描述和理解我也都省去了。如果你也是从其他语言转到Python,这本书就是简单的语法教学,我也相信你能很快的阅读完。要注意的地方,我也都写在代码的注解里了。如果你是一个编程萌新,书里面的代码,以及作业自己要好好琢磨一下,毕竟有些东西对于熟悉编程的人来讲很容易明白甚至不用说明,但对于初学者可能理解就要花一些时间,比方说嵌套,比方说递归。
《Python编程,从入门到实践》书如其名,入门-实践。适合人群的话,初学Python,或者编程萌新,我更倾向于适用于编程萌新,如果你是其他语言转Python或者需要用到,这本书的内容远不够你用,而且大段你都会觉得在说废话,我倾向于你看看blog或者视频快速掌握基本语法,然后看其他书深入。