{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 递归 Recursion" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def fact(n):\n", " # 定义递归的出口\n", " if n == 0 or n == 1:\n", " return 1\n", " # 定义递归的分解\n", " return n * fact(n-1)\n", "\n", "print(fact(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 类 Class" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Student(object):\n", " def __init__(self, name, score):\n", " self.name = name\n", " self.score = score\n", " \n", " def print_info(self):\n", " print(self.name, self.score)\n", " \n", " \n", "# 实例化对象\n", "student1 = Student('Jack', 98)\n", "student2 = Student('Rose', 99)\n", "\n", "\n", "# 在这个调用中,self == student1\n", "student1.print_info()\n", "# 在这个调用中,self == student2\n", "student2.print_info()\n", "\n", "# 你也可以不叫它self,改成my或者任何变量名也是可以的...\n", "\n", "# 通过.在外部访问成员变量和调用成员函数\n", "student1.score = 100\n", "student1.print_info()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 封装性" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Cat(object):\n", " def __init__(self, name):\n", " self.name = name\n", " # 私有变量\n", " self.__owner = \"Andrew\"\n", " \n", " # 私有方法\n", " def __private_speak(self):\n", " print(\"{}: miao~\".format(self.name))\n", " \n", " # 约定俗成: 类似protect\n", " def _speak(self):\n", " print(\"miao miao~\")\n", " \n", " # 公开方法\n", " def speak(self):\n", " print(\"miao!\")\n", " \n", " def expose_private_speak(self):\n", " # 私有方法可在类内部调用\n", " self.__private_speak()\n", " \n", " def check_owner(self):\n", " return self.__owner\n", " \n", " def check_owner_memory_addr(self):\n", " # id: unique id of a variable. This is the address of the object in memory.\n", " # hex: 转换成十六进制\n", " return hex(id(self.__owner))\n", " \n", " # 覆盖字符串表示方法\n", " def __str__(self):\n", " return \"This is a cat named: {}\".format(self.name)\n", " \n", " # 覆盖加法操作\n", " def __add__(self, other):\n", " return Cat(self.name + other.name + \"Kid\")\n", " \n", "\n", "my_cat = Cat(\"Jane\")\n", "\n", "# 有什么不同\n", "print(Cat)\n", "print(my_cat)\n", "\n", "# 可调用\n", "my_cat.speak()\n", "# 可调用,但不建议调用者使用\n", "my_cat._speak()\n", "\n", "# 不可调用\n", "#my_cat.__private_speak()\n", "\n", "# 可调用\n", "my_cat.expose_private_speak()\n", "\n", "# 其它访问类属性的方法\n", "print(hasattr(my_cat, 'name'))\n", "print(getattr(my_cat, 'name'))\n", "print(setattr(my_cat, 'name', 'JaneCat'))\n", "print(my_cat.name)\n", "\n", "# 如果设置一个不存在的属性,会临定到类的临时成员变量中\n", "setattr(my_cat, 'age', 1)\n", "print(my_cat.age)\n", "\n", "# 这个例子会发生什么?\n", "# print(my_cat.__owner)\n", "setattr(my_cat, '__owner', 'Monica')\n", "# 为什么可以访问了呢???\n", "print(my_cat.__owner)\n", "# 这还是Andrew\n", "print(my_cat.check_owner())\n", "# 打印内存地址发现是不同的变量,存在两个不同的内存空间\n", "print(hex(id(my_cat.__owner)))\n", "print(my_cat.check_owner_memory_addr())\n", "\n", "# 也可以检查函数是否存在\n", "print(hasattr(my_cat, 'expose_private_speak'))\n", "# 也可以获得方法,使用场景: 当其他人动态给你传递一个object以及一个方法名,你就可以这样调用\n", "getattr(my_cat, 'expose_private_speak')()\n", "\n", "# 特殊函数__str__\n", "print(my_cat)\n", "\n", "# 特殊函数__add__\n", "my_second_cat = Cat(\"Dan\")\n", "# Jane和Dan生下一只小猫\n", "my_little_kitten = my_cat + my_second_cat\n", "print(my_little_kitten)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 类的运算覆盖" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 对象的排序\n", "\n", "# 定义类表示二维坐标(x,y)上的点\n", "class Point(object):\n", " def __init__(self, x, y):\n", " self.x = x\n", " self.y = y\n", " \n", " def __lt__(self, other): # 定义“小于符号”\n", " if self.x != other.x:\n", " return self.x < other.x\n", " return self.y < other.y\n", "\n", "points = [Point(3, 10), Point(4, 2), Point(3, -1), Point(1, -1), Point(4, 10)]\n", "points.sort()\n", "\n", "for p in points:\n", " print(p.x, p.y)\n", " \n", "points.sort(reverse=True)\n", "\n", "for p in points:\n", " print(p.x, p.y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 使用@property" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class StudentNoPythonic(object):\n", " def __init__(self, name, score):\n", " self.name = name\n", " self.__score = score\n", " \n", " def print_info(self):\n", " print(self.name, self.__score)\n", " \n", " def get_score(self):\n", " return self.__score\n", " \n", " def set_score(self, value):\n", " # assert (断言): 如果True则通过,如果False则报错\n", " assert isinstance(value, int)\n", " assert 0 <= value <= 100\n", " self.__score = value\n", "\n", "student1 = StudentNoPythonic(\"Jack\", 80)\n", "print(student1.get_score())\n", "\n", "# 不符合第一个assert \n", "# student1.set_score(120.98)\n", "\n", "# 不符合第二个assert\n", "# student1.set_score(101)\n", "\n", "# 合法操作\n", "student1.set_score(100)\n", "print(student1.get_score())\n", "\n", "\n", "class StudentPythonic(object):\n", " def __init__(self, name, score):\n", " self.name = name\n", " self.__score = score\n", " \n", " def print_info(self):\n", " print(self.name, self.__score)\n", " \n", " @property\n", " def score(self):\n", " return self.__score\n", " \n", " @score.setter\n", " def score(self, value):\n", " assert isinstance(value, int)\n", " assert 0 <= value <= 100\n", " self.__score = value\n", "\n", "student2 = StudentPythonic(\"Dan\", 80)\n", "# 跟成员变量一样的用法,让调用者保持一致的体验\n", "print(student2.score)\n", "\n", "# 不符合第一个assert \n", "# student2.score = 120.98\n", "\n", "# 不符合第二个assert\n", "# student2.score = 101\n", "\n", "# 合法操作, 跟成员变量一样的用法,让调用者保持一致的体验\n", "student2.score = 100\n", "print(student2.score)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 类的继承Inheritance" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Animal(object):\n", " def __init__(self, name):\n", " self.name = name\n", " self.__color = 'red'\n", " \n", " def get_name(self):\n", " return self.name\n", " \n", " def get_color(self):\n", " return self.__color\n", " \n", " def _get_color(self):\n", " return self.__color\n", " \n", " def __get_color(self):\n", " return self.__color\n", " \n", " def speak(self):\n", " return '...'\n", "\n", "class Dog(Animal):\n", " def __init__(self, name):\n", " # 调用父类的初始化函数\n", " super().__init__(name)\n", " \n", " def speak(self):\n", " return self.name + \": Wong!\"\n", "\n", "class Husky(Dog):\n", " def __init__(self, name):\n", " # 调用父类的初始化函数\n", " super().__init__(name) \n", " \n", "dog = Dog(\"Doge\")\n", "# 被继承了\n", "print(dog.speak())\n", "# 被继承了\n", "print(dog.get_color())\n", "# 被继承了\n", "print(dog._get_color())\n", "# 私有方法没有被继承\n", "#print(dog.__get_color())\n", "\n", "husky = Husky(\"White\")\n", "# 它会调用哪个函数?\n", "print(husky.speak()) \n", "\n", "# isinstance检查对象的类型\n", "animal = Animal('Dragon')\n", "print(isinstance(dog, Dog))\n", "print(isinstance(dog, Animal))\n", "print(isinstance(animal, Animal))\n", "print(isinstance(animal, Dog))\n", "\n", "# 类属性\n", "class Cat(Animal):\n", " type = 'Cat'\n", " cat_id = 0\n", " \n", " def __init__(self, name):\n", " # 调用父类的初始化函数\n", " super().__init__(name)\n", " # self.cat_id (对象变量) 与 Cat.cat_id (类变量)\n", " self.cat_id = Cat.cat_id\n", " Cat.cat_id += 1\n", " \n", "alice = Cat('Alice')\n", "bob = Cat('Bob')\n", "\n", "# type属于Cat类,在每个对象中也可以访问, cat_id在对象和类的区别\n", "print(Cat.type, Cat.cat_id)\n", "print(alice.type, alice.cat_id, Cat.cat_id)\n", "print(bob.type, bob.cat_id, Cat.cat_id)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 多重继承" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 多重继承就是一个类可以继承自多个父类\n", "\n", "class Animal(object):\n", " pass\n", "\n", "class Mammal(Animal):\n", " def reproduction(self):\n", " print('viviparous') #胎生\n", "\n", "class Bird(Animal):\n", " def reproduction(self):\n", " print('Oviparous') #卵生\n", "\n", "class Runnable(Animal): # 地上跑的\n", " def move(self):\n", " print('Run')\n", "\n", "class Flyable(Animal): # 天上飞的\n", " def move(self):\n", " print('Fly')\n", "\n", "class Dog(Mammal, Runnable):\n", " pass\n", "\n", "dog = Dog()\n", "dog.reproduction()\n", "dog.move()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# python的多态是假多态 (这个概念在python里被弱化)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 类的多态可以简单理解为父类可以访问到不同子类的方法和属性\n", "\n", "# 定义Animal为父类\n", "class Animal(object):\n", " def run(self):\n", " print(\"Animal is running!\")\n", "\n", "# 定义一个与Animal对象交互的函数\n", "def playWithAnimal(animal):\n", " animal.run()\n", "\n", "# 调用\n", "playWithAnimal(Animal())\n", "\n", "# 定义Dog继承自Animal\n", "class Dog(Animal):\n", " def run(self):\n", " print(\"Dog is running!\")\n", "\n", "# 把Dog当作它的父类Animal的实例放入函数也是可以的(多态的概念)\n", "playWithAnimal(Dog())\n", "\n", "# 但是... Python是不区分类型的,定义一个类不继承自Animal但是也有run函数\n", "class Car(object):\n", " def run(self):\n", " print(\"Car is running!\")\n", "\n", "# playWithAnimal也开始可以接受这个类的对象的\n", "playWithAnimal(Car())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 异常Exception" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 抛一个异常\n", "# a = 100 / 0\n", "\n", "# 异常是可以捕捉的\n", "a, b = None, None\n", "try:\n", " a = 2\n", "except:\n", " b = 1\n", "else:\n", " b = 200\n", "\n", "print(a, b)\n", "\n", "a, b = None, None\n", "try:\n", " a[1] = 2\n", "except:\n", " b = 1\n", "else:\n", " b = 200\n", "\n", "print(a, b)\n", "\n", "# 捕获特定异常\n", "try: \n", " a = 100 / 0\n", "except ZeroDivisionError:\n", " a = 0\n", "\n", "print(a)\n", "\n", "# 下面的代码还是会报错,因为没有捕获ZeroDivisionError\n", "# try: \n", "# a = 100 / 0\n", "# except RuntimeError:\n", "# a = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 文件读写" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tmp_writer = open(\"temp.txt\", \"w\")\n", "tmp_writer.write(\"This is a temp file.\\n\")\n", "tmp_writer.write(\"This is the second line.\\n\")\n", "tmp_writer.write(\"This is the end of the flie.\\n\")\n", "tmp_writer.close()\n", "\n", "tmp_reader = open(\"temp.txt\", 'r')\n", "# 读一行\n", "print(tmp_reader.readline())\n", "# 读全部\n", "print(tmp_reader.read())\n", "tmp_reader.close()\n", "\n", "# 加载一个已有的库\n", "import os\n", "\n", "# 创建文件夹\n", "os.makedirs('data', exist_ok=True)\n", "\n", "# 判断文件是否存在并重命名\n", "if os.path.exists('temp.txt'):\n", " os.rename('temp.txt', 'data/demo.txt')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Json数据格式" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import json\n", "\n", "data = {\n", " 'name': 'Alice',\n", " 'age': 33,\n", " 'salary': 20000,\n", " 'sex': 'female',\n", " 'degree': 'master'\n", "}\n", "# 展示数据\n", "display(data)\n", "\n", "# 编码数据\n", "info = json.dumps(data)\n", "\n", "# 展示编码\n", "display(info)\n", "\n", "# 展示解码\n", "display(json.loads(info))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# CSV" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import csv\n", "\n", "# with statement \n", "with open('names.csv', 'w') as csvfile:\n", " fieldnames = ['first_name', 'last_name']\n", " writer = csv.DictWriter(csvfile, fieldnames=fieldnames)\n", " # 写入header\n", " writer.writeheader()\n", " # 写入数据\n", " writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})\n", " writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})\n", " writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})\n", " \n", "\n", "with open('names.csv') as csvfile:\n", " reader = csv.DictReader(csvfile)\n", " for row in reader:\n", " print(row['first_name'], row['last_name']) " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }