Update: 关于numpy和scipy,这里有一些总结
摘自Python - 100天从新手到大师,链接:https://github.com/jackfrued/Python-100-Days
Day 06 函数和模块的使用 python 不支持函数重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式,比如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from random import randintdef roll_dice (n=2 ): """摇色子""" total = 0 for _ in range (n): total += randint(1 , 6 ) return total def add (a=0 , b=0 , c=0 ): """三个数相加""" return a + b + c print (roll_dice())print (roll_dice(3 ))print (add())print (add(1 ))print (add(1 , 2 ))print (add(1 , 2 , 3 ))print (add(c=50 , a=100 , b=200 ))
在不确定参数个数的时候,我们可以使用可变参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def add (*args ): total = 0 for val in args: total += val return total print (add())print (add(1 ))print (add(1 , 2 ))print (add(1 , 2 , 3 ))print (add(1 , 3 , 5 , 7 , 9 ))
然而,如果在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。
因此,使用 from filename import functioname
需要说明的是,如果我们导入的模块除了定义函数之外还有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是”main “。
module3.py
1 2 3 4 5 6 7 8 9 10 11 12 13 def foo (): pass def bar (): pass if __name__ == '__main__' : print ('call foo()' ) foo() print ('call bar()' ) bar()
python 中的交换赋值 :
1 2 3 4 5 6 def gcd (x, y ): """求最大公约数""" (x, y) = (y, x) if x > y else (x, y) for factor in range (x, 0 , -1 ): if x % factor == 0 and y % factor == 0 : return factor
(讲真一般不是用辗转相除嘛…)
1 2 3 4 5 6 7 a, b = map (int , input ("enter two numbers" ).split()) c = a % b while c : a = b b = c c = a % b print (b)
Day 07 字符串和常用数据结构 如果不希望字符串中的\
表示转义,我们可以通过在字符串的最前面加上字母r
来加以说明
1 2 3 s1 = r'\'hello, world!\'' s2 = r'\n\\hello, world!\\\n' print (s1, s2, end='' )
在Python中,我们还可以通过一系列的方法来完成对字符串的处理,代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 str1 = 'hello, world!' print (len (str1)) print (str1.capitalize()) print (str1.title()) print (str1.upper()) print (str1.find('or' )) print (str1.find('shit' )) print (str1.startswith('He' )) print (str1.startswith('hel' )) print (str1.endswith('!' )) print (str1.center(50 , '*' ))print (str1.rjust(50 , ' ' ))str2 = 'abc123456' print (str2.isdigit()) print (str2.isalpha()) print (str2.isalnum()) str3 = ' jackfrued@126.com ' print (str3)print (str3.strip())
Python 支持格式化输出 Further information: https://www.geeksforgeeks.org/python-string-format-method
1 2 3 4 5 6 7 8 9 a, b = 5 , 10 print ('%d * %d = %d' % (a, b, a * b))a, b = 5 , 10 print ('{0} * {1} = {2}' .format (a, b, a * b))a, b = 5 , 10 print (f'{a} * {b} = {a * b} ' )
Emunerate function
1 2 3 4 5 6 7 8 9 l1 = ["eat" ,"sleep" ,"repeat" ] s1 = "geek" obj1 = enumerate (l1) obj2 = enumerate (s1) print ("Return type:" ,type (obj1)) print (list (enumerate (l1))) print (list (enumerate (s1,2 )))
sorted function
1 2 3 4 5 numbers = [4 , 2 , 12 , 8 ] sorted_numbers = sorted (numbers) print (sorted_numbers)
生成式和生成器 使用生成式语法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import sysf = [x for x in range (1 , 10 )] print (f)f = [x + y for x in 'ABCDE' for y in '1234567' ] print (f)f = [x ** 2 for x in range (1 , 1000 )] print (sys.getsizeof(f)) print (f)f = (x ** 2 for x in range (1 , 1000 )) print (sys.getsizeof(f)) print (f)for val in f: print (val)
使用yeild
关键字将一个普通函数改造成生成器函数:
1 2 3 4 5 6 7 8 9 10 11 12 def fib (n ): a, b = 0 , 1 for _ in range (n): a, b = b, a + b yield a def main (): for val in fib(20 ): print (val) if __name__ == '__main__' : main()
关于if __name__ == '__main__'
,请看https://stackoverflow.com/questions/419163/what-does-if-name-main-do?page=2&tab=votes#tab-top
集合(set) 创建集合:
1 2 3 4 5 6 7 8 9 10 11 12 13 set1 = {1 , 2 , 3 , 3 , 3 , 2 } print (set1)print ('Length =' , len (set1))set2 = set (range (1 , 10 )) set3 = set ((1 , 2 , 3 , 3 , 2 , 1 )) print (set2, set3)set4 = {num for num in range (1 , 100 ) if num % 3 == 0 or num % 5 == 0 } print (set4)
向集合添加元素和从集合删除元素:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 set1.add(4 ) set1.add(5 ) set2.update([11 , 12 ]) set2.discard(5 ) if 4 in set2: set2.remove(4 ) print (set1, set2)print (set3.pop())print (set3)
集合的成员、交集、并集、差集等运算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 print (set1 & set2)print (set1 | set2)print (set1 - set2)print (set1 ^ set2)print (set2 <= set1)print (set3 <= set1)print (set1 >= set2)print (set1 >= set3)
字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 scores = {'骆昊' : 95 , '白元芳' : 78 , '狄仁杰' : 82 } print (scores)items1 = dict (name = "John" , age = 36 , country = "Norway" ) items2 = dict (zip (['a' , 'b' , 'c' ], '123' )) items3 = {num: num ** 2 for num in range (1 , 10 )} print (items1, items2, items3)print (scores['骆昊' ])print (scores['狄仁杰' ])for key in scores: print (f'{key} : {scores[key]} ' ) scores['白元芳' ] = 65 scores['诸葛王朗' ] = 71 scores.update(冷面=67 , 方启鹤=85 ) print (scores)if '武则天' in scores: print (scores['武则天' ]) print (scores.get('武则天' ))print (scores.get('武则天' , 60 ))print (scores.popitem())print (scores.popitem())print (scores.pop('骆昊' , 100 ))scores.clear() print (scores)
练习摘录 1.设计一个函数返回给定文件名的后缀名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def get_suffix (filename, has_dot=False ): """ 获取文件名的后缀名 :param filename: 文件名 :param has_dot: 返回的后缀名是否需要带点 :return: 文件的后缀名 """ pos = filename.rfind('.' ) if 0 < pos < len (filename) - 1 : index = pos if has_dot else pos + 1 return filename[index:] else : return ''
2.计算指定的年月日是这一年的第几天
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 def is_leap_year (year ): """ 判断指定的年份是不是闰年 :param year: 年份 :return: 闰年返回True平年返回False """ return year % 4 == 0 and year % 100 != 0 or year % 400 == 0 def which_day (year, month, date ): """ 计算传入的日期是这一年的第几天 :param year: 年 :param month: 月 :param date: 日 :return: 第几天 """ days_of_month = [ [31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ], [31 , 29 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ] ][is_leap_year(year)] total = 0 for index in range (month - 1 ): total += days_of_month[index] return total + date def main (): print (which_day(1980 , 11 , 28 )) print (which_day(1981 , 12 , 31 )) print (which_day(2018 , 1 , 1 )) print (which_day(2016 , 3 , 1 )) if __name__ == '__main__' : main()
这里其实有点没看懂list初始化的部分,搜了一下python还有一个itertools.compress()
函数:
1 2 3 4 5 6 7 8 9 10 11 import itertoolsimport operatorCodes =['C' , 'C++' , 'Java' , 'Python' ] selectors = [False , False , False , True ] Best_Programming = itertools.compress(Codes, selectors) for each in Best_Programming: print (each)
“itertools
— 为高效循环而创建迭代器的函数”https://docs.python.org/zh-cn/3/library/itertools.html
Day 08 面向对象编程基础 在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Test : def __init__ (self, foo ): self.__foo = foo def __bar (self ): print (self.__foo) print ('__bar' ) def main (): test = Test('hello' ) test.__bar() print (test.__foo) if __name__ == "__main__" : main()
但是,Python并没有从语法上严格保证私有属性或方法的私密性,它只是给私有的属性和方法换了一个名字来妨碍对它们的访问,事实上如果你知道更换名字的规则仍然可以访问到它们:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Test : def __init__ (self, foo ): self.__foo = foo def __bar (self ): print (self.__foo) print ('__bar' ) def main (): test = Test('hello' ) test._Test__bar() print (test._Test__foo) if __name__ == "__main__" : main()
在实际开发中,我们并不建议将属性设置为私有的,因为这会导致子类无法访问。所以大多数Python程序员会遵循一种命名惯例就是让属性名以单 下划线开头来表示属性是受保护的,本类之外的代码在访问这样的属性时应该要保持慎重。这种做法并不是语法上的规则,单下划线开头的属性和方法外界仍然是可以访问的,所以更多的时候它是一种暗示或隐喻
Day 09 面向对象进阶 函数装饰器 详见:https://www.runoob.com/w3cnote/python-func-decorators.html
关于*args
,**kwargs
,详见:https://www.geeksforgeeks.org/args-kwargs-python/#:~:text=The%20special%20syntax%20*args%20in,used%20with%20the%20word%20args .
使用@property包装器来包装属性的getter(访问器)和setter(修改器)方法,使得对属性的访问既安全又方便:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Person (object ): def __init__ (self, name, age ): self._name = name self._age = age @property def name (self ): return self._name @property def age (self ): return self._age @age.setter def age (self, age ): self._age = age def play (self ): if self._age <= 16 : print ('%s正在玩飞行棋.' % self._name) else : print ('%s正在玩斗地主.' % self._name) def main (): person = Person('王大锤' , 12 ) person.play() person.age = 22 person.play() if __name__ == '__main__' : main()
关于class(object)
: object is the mother of all classes in Python. Declaring it as a new-style class in Python2. https://stackoverflow.com/questions/7375595/class-with-object-as-a-parameter
__slots__魔法 Python是一门动态语言。通常,动态语言允许我们在程序运行时给对象绑定新的属性或方法,当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__
变量来进行限定。需要注意的是__slots__
的限定只对当前类的对象生效,对子类并不起任何作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Person (object ): __slots__ = ('_name' , '_age' , '_gender' ) def __init__ (self, name, age ): self._name = name self._age = age @property def name (self ): return self._name @property def age (self ): return self._age @age.setter def age (self, age ): self._age = age def play (self ): if self._age <= 16 : print ('%s正在玩飞行棋.' % self._name) else : print ('%s正在玩斗地主.' % self._name) def main (): person = Person('王大锤' , 22 ) person.play() person._gender = '男'
静态方法和类方法 静态方法:可以在生成对象之前运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 from math import sqrtclass Triangle (object ): def __init__ (self, a, b, c ): self._a = a self._b = b self._c = c @staticmethod def is_valid (a, b, c ): return a + b > c and b + c > a and a + c > b def perimeter (self ): return self._a + self._b + self._c def area (self ): half = self.perimeter() / 2 return sqrt(half * (half - self._a) * (half - self._b) * (half - self._c)) def main (): a, b, c = 3 , 4 , 5 if Triangle.is_valid(a, b, c): t = Triangle(a, b, c) print (t.perimeter()) print (t.area()) else : print ('无法构成三角形.' ) if __name__ == '__main__' : main()
和静态方法比较类似,Python还可以在类中定义类方法,类方法的第一个参数约定名为cls
,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象 classmethod
修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 from time import time, localtime, sleepclass Clock (object ): """数字时钟""" def __init__ (self, hour=0 , minute=0 , second=0 ): self._hour = hour self._minute = minute self._second = second @classmethod def now (cls ): ctime = localtime(time()) return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec) def run (self ): """走字""" self._second += 1 if self._second == 60 : self._second = 0 self._minute += 1 if self._minute == 60 : self._minute = 0 self._hour += 1 if self._hour == 24 : self._hour = 0 def show (self ): """显示时间""" return '%02d:%02d:%02d' % \ (self._hour, self._minute, self._second) def main (): clock = Clock.now() while True : print (clock.show()) sleep(1 ) clock.run() if __name__ == '__main__' : main()
The time()
function returns the number of seconds passed since epoch. The localtime()
function takes the number of seconds passed since epoch as an argument and returns struct_time
in local time.
Attributes of struct_time
:
Difference between static method and class method: https://stackoverflow.com/questions/136097/difference-between-staticmethod-and-classmethod
继承 注意__init__
的部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 class Person (object ): """人""" def __init__ (self, name, age ): self._name = name self._age = age @property def name (self ): return self._name @property def age (self ): return self._age @age.setter def age (self, age ): self._age = age def play (self ): print ('%s正在愉快的玩耍.' % self._name) def watch_av (self ): if self._age >= 18 : print ('%s正在观看爱情动作片.' % self._name) else : print ('%s只能观看《熊出没》.' % self._name) class Student (Person ): """学生""" def __init__ (self, name, age, grade ): super ().__init__(name, age) self._grade = grade @property def grade (self ): return self._grade @grade.setter def grade (self, grade ): self._grade = grade def study (self, course ): print ('%s的%s正在学习%s.' % (self._grade, self._name, course)) class Teacher (Person ): """老师""" def __init__ (self, name, age, title ): super ().__init__(name, age) self._title = title @property def title (self ): return self._title @title.setter def title (self, title ): self._title = title def teach (self, course ): print ('%s%s正在讲%s.' % (self._name, self._title, course)) def main (): stu = Student('王大锤' , 15 , '初三' ) stu.study('数学' ) stu.watch_av() t = Teacher('骆昊' , 38 , '砖家' ) t.teach('Python程序设计' ) t.watch_av() if __name__ == '__main__' : main()
多态 Python从语法层面并没有像Java或C#那样提供对抽象类的支持,但是我们可以通过abc
(Abstract Base Class)模块的ABCMeta
元类和abstractmethod
包装器来达到抽象类的效果,如果一个类中存在抽象方法那么这个类就不能够实例化(创建对象)。https://www.geeksforgeeks.org/abstract-base-class-abc-in-python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 from abc import ABCMeta, abstractmethodclass Pet (object , metaclass=ABCMeta ): """宠物""" def __init__ (self, nickname ): self._nickname = nickname @abstractmethod def make_voice (self ): """发出声音""" pass class Dog (Pet ): """狗""" def make_voice (self ): print ('%s: 汪汪汪...' % self._nickname) class Cat (Pet ): """猫""" def make_voice (self ): print ('%s: 喵...喵...' % self._nickname) def main (): pets = [Dog('旺财' ), Cat('凯蒂' ), Dog('大黄' )] for pet in pets: pet.make_voice() if __name__ == '__main__' : main()
str method the __str__
method is called when the following functions are invoked on the object and return a string:
print()
str()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class MyClass : x = 0 y = "" def __init__ (self, anyNumber, anyString ): self.x = anyNumber self.y = anyString def __str__ (self ): return 'MyClass(x=' + str (self.x) + ' ,y=' + self.y + ')' myObject = MyClass(12345 , "Hello" ) print (myObject.__str__())print (myObject)print (str (myObject))print (myObject.__repr__())
hasattr() method Python hasattr() function is an inbuilt utility function, which is used to check if an object has the given named attribute and return true if present, else false.
1 2 3 4 5 6 7 8 9 10 11 12 class GfG (object ): name = "GeeksforGeeks" age = 24 obj = GfG() print ("Does name exist ? " + str (hasattr (obj, 'name' )))print ("Does motto exist ? " + str (hasattr (obj, 'motto' )))
isinstance() method Python isinstance() function returns True if the object is specified types, and it will not match then return False.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 test_int = 5 test_list = [1 , 2 , 3 ] print ("Is test_int integer? : " + str (isinstance (test_int, int )))print ("Is test_int string? : " + str (isinstance (test_int, str )))print ("Is test_list integer? : " + str (isinstance (test_list, int )))print ("Is test_list list? : " + str (isinstance (test_list, list )))print ("Is test_int integer or list or string? : " + str (isinstance (test_int, (list , int ))))
getattr()
1 2 3 4 5 6 7 8 9 10 11 12 13 >>>class A (object ): ... bar = 1 ... >>> a = A()>>> getattr (a, 'bar' ) 1 >>> getattr (a, 'bar2' ) Traceback (most recent call last): File "<stdin>" , line 1 , in <module> AttributeError: 'A' object has no attribute 'bar2' >>> getattr (a, 'bar2' , 3 ) 3 >>>
Day10 图形用户界面和游戏开发 nonlocal keyword
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 def geek_func (): geek_name = "geek" def geek_func2 (): nonlocal geek_name geek_name = 'GeekForGeeks' print (geek_name) geek_func2() print (geek_name) geek_func()
详见:https://blog.csdn.net/xCyansun/article/details/79672634
@unique @unique
is a class decorator specifically for enumerations. It searches an enumeration’s members gathering any aliases it finds; if any are found ValueError is raised with the details. Basically, it raises an error if there are any duplicate enumeration values.
1 2 3 4 5 6 7 8 9 10 from enum import unique, Enum@unique class Mistake (Enum ): ONE = 1 TWO = 2 THREE = 3 FOUR = 3
这里的Enum
跟c中作用类似
这次讲的内容感觉跟海龟绘图差不多,因为大一上学过了所以只贴一个链接:https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/10。%E5%9B%BE%E5%BD%A2%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E5%92%8C%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91.md
Day 11 文件和异常 在Python中实现文件的读写操作其实非常简单,通过Python内置的open函数,我们可以指定文件名、操作模式、编码信息等来获得操作文件的对象,接下来就可以对文件进行读写操作了。这里所说的操作模式是指要打开什么样的文件(字符文件还是二进制文件)以及做什么样的操作(读、写还是追加),具体的如下表所示。
操作模式
具体含义
'r'
读取 (默认)
'w'
写入(会先截断之前的内容)
'x'
写入,如果文件已经存在会产生异常
'a'
追加,将内容写入到已有文件的末尾
'b'
二进制模式
't'
文本模式(默认)
'+'
更新(既可以读又可以写)
读写文本文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def main (): f = None try : f = open ('致橡树.txt' , 'r' , encoding='utf-8' ) print (f.read()) except FileNotFoundError: print ('无法打开指定的文件!' ) except LookupError: print ('指定了未知的编码!' ) except UnicodeDecodeError: print ('读取文件时解码错误!' ) finally : if f: f.close() if __name__ == '__main__' : main()
在Python中,我们可以将那些在运行时可能会出现状况的代码放在try
代码块中,在try
代码块的后面可以跟上一个或多个except
来捕获可能出现的异常状况。例如在上面读取文件的过程中,文件找不到会引发FileNotFoundError
,指定了未知的编码会引发LookupError
,而如果读取文件时无法按指定方式解码会引发UnicodeDecodeError
,我们在try
后面跟上了三个except
分别处理这三种不同的异常状况。最后我们使用finally
代码块来关闭打开的文件,释放掉程序中获取的外部资源,由于finally
块的代码不论程序正常还是异常都会执行到(甚至是调用了sys
模块的exit
函数退出Python环境,finally
块都会被执行,因为exit
函数实质上是引发了SystemExit
异常),因此我们通常把finally
块称为“总是执行代码块”,它最适合用来做释放外部资源的操作。如果不愿意在finally
代码块中关闭文件对象释放资源,也可以使用上下文语法,通过with
关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源,代码如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def main (): try : with open ('致橡树.txt' , 'r' , encoding='utf-8' ) as f: print (f.read()) except FileNotFoundError: print ('无法打开指定的文件!' ) except LookupError: print ('指定了未知的编码!' ) except UnicodeDecodeError: print ('读取文件时解码错误!' ) if __name__ == '__main__' : main()
yeild
Supporting the “with” statement in user defined objects: https://www.geeksforgeeks.org/with-statement-in-python/