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 支持格式化输出 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 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__魔法 __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.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() 
多态 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__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 
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 
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.
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/