《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("
ditto")

异常

# 异常
# 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或者视频快速掌握基本语法,然后看其他书深入。

原文地址:https://www.cnblogs.com/Moriarty-cx/p/12286729.html