effective python === ###### tags:`python` # map and filter ```python from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = "all" ``` ```python a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] squares = map(lambda x: x ** 2, a) [x for x in squares] ``` [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] ```python squares=filter(lambda x:x%2==0,a) [x for x in squares] ``` [2, 4, 6, 8, 10] ```python [x**2 for x in a] ``` [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # enumerate ```python lolis=['loli1','loli2','loli3','loli4','loli5'] for index,value in enumerate(lolis): print((index,value)) ``` (0, 'loli1') (1, 'loli2') (2, 'loli3') (3, 'loli4') (4, 'loli5') ```python # change start from index for index,value in enumerate(lolis,5): print((index,value)) ``` (5, 'loli1') (6, 'loli2') (7, 'loli3') (8, 'loli4') (9, 'loli5') # zip ```python brothers=["brother1","brother2","brother3","brother4"] for i in zip(lolis,brothers): print(i) ``` ('loli1', 'brother1') ('loli2', 'brother2') ('loli3', 'brother3') ('loli4', 'brother4') # else after for ```python for i in range(2): print(i) if i % 2 == 0: break else: print('loop finish') ``` 0 # reversed iterate ```python list_example = [i for i in range(5)] iter_example = (i for i in range(5)) set_example = {i for i in range(5)} list_example iter_example set_example ``` [0, 1, 2, 3, 4] <generator object <genexpr> at 0x7fc7b0a6f990> {0, 1, 2, 3, 4} ```python for i in reversed(list_example): print(i) ``` 4 3 2 1 0 ```python for i in reversed(iter_example): print(i) ``` --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-30-06c418582e31> in <module>() ----> 1 for i in reversed(iter_example): 2 print(i) TypeError: argument to reversed() must be a sequence ```python for i in reversed(set_example): print(i) ``` --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-31-5660da0e6339> in <module>() ----> 1 for i in reversed(set_example): 2 print(i) TypeError: argument to reversed() must be a sequence ```python reversed(list_example) ``` <list_reverseiterator at 0x7fc7b09cb358> ```python class countdown(object): def __init__(self,start): self.start=start def __iter__(self): n=self.start while n>0: yield n n-=1 def __reversed__(self): n=1 while n<=self.start: yield n n+=1 for i in reversed(countdown(4)): print(i) ``` 1 2 3 4 ```python for i in countdown(4): print(i) ``` 4 3 2 1 ```python count_rev=reversed(countdown(100)) next(count_rev) ``` 1 # for/try/else 若執行try沒有發生異常,則執行else,for 則是執行時若沒有break,則會執行else ```python try: print("loli OUOb") except: print("except occure!") else: print("else statment") finally: print("finally statement") ``` loli OUOb else statment finally statement ```python for x in [4,5,6,7,8]: if x>10: break else: print("Hello world!") ``` Hello world! # decorator ```python def more(fun): def new_fun(*args,**kwargs): print('current fun:',fun.__name__) print('arguments"',args) print('key arguments:',kwargs) result=fun(*args,**kwargs) print('result:',result) return result return new_fun @more def add(a,b): return a+b add(5,10) ``` current fun: add arguments" (5, 10) key arguments: {} result: 15 15 ## 在decorater加入參數 ```python def read_file(filename=''): def more(fun): print(filename) def new_fun(*args,**kwargs): print('current fun:',fun.__name__) print('arguments"',args) print('key arguments:',kwargs) result=fun(*args,**kwargs) print('result:',result) return result return new_fun return more # pass argument into decorator @read_file(filename='log.txt') def add(a, b): return a + b @more def add(a, b): return a + b print(add.__name__) # decorate func name wiil change ``` log.txt new_fun ## functools.wraps ```python from functools import wraps def decorator_fun(fun): @wraps(fun) def new_fun(*args, **kwargs): result = fun(*args, **kwargs) print(result) return result return new_fun @decorator_fun def add(a, b): return a + b print(add.__name__) add(5,10) ``` add 15 15 ## using the __call__ method ```python from functools import wraps class logResult(object): def __init__(self, filename='results.txt'): self.filename = filename def __call__(self, fun): @wraps(fun) def new_fun(*args, **kwargs): result = fun(*args, **kwargs) with open(filename, 'a') as f: f.write(result + '\n') return result self.send_notification() return new_fun def send_notification(self): pass @logResult('log.txt') def add(a, b): return a + b print(add.__name__) ``` add # iterable ```python def loop(items): for i in items: yield i foo = loop([1, 2, 3, 4]) for i in foo: print(i) # the list of generator can only be print once # will print nothing for i in foo: print(i) ``` 1 2 3 4 ## use itrable class to iterate again ```python class LoopIter(object): def __init__(self, data): self.data = data def __iter__(self): for index, letter in enumerate(self.data): if letter == 'a': yield index string = 'this is a test to find a\' index' indexs = LoopIter(string) print('loop 1') for _ in indexs: print(_) # can be print twice print('loop 2') for _ in indexs: print(_) ``` loop 1 8 23 loop 2 8 23 but the \__iter\__ method can only be iterate by for loop. If you wan't to iterate by next you have to use the `iter` function ```python string = 'this is a test to find a\' index' indexs = LoopIter(string) # next(indexs) # TypeError: 'LoopIter' object is not an iterator iter_indexs = iter(indexs) next(iter_indexs) ``` 8 # sending multiple argument into function ```python def square(*args): result=0 for i in args: result+=i**2 return result square(1,2,3,4,5) square(*[1,3,4,5,6,7]) ``` 55 136 # 關鍵字參數 ```python def get_indexs(array, *, target='', judge=True): for index, item in enumerate(array): if judge and item == target: yield index elif not judge and item != target: yield index array = [1, 2, 3, 4, 1] result = get_indexs(array, target=1, judge=True) print(*result) # can ignore result = get_indexs(array, target=1) print(*result) ``` 0 4 0 4 > you have to specfic the argument ```python result=get_indexs(array,1,False) ``` --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-98-de1480137b59> in <module>() ----> 1 result=get_indexs(array,1,False) TypeError: get_indexs() takes 1 positional argument but 3 were given # default argument in function ```python def get_default(value=[]): return value result = get_default() result.append(1) result2 = get_default() result2.append(2) print(result) # [1, 2] print(result2) # [1, 2] ``` [1, 2] [1, 2] ```python def get_default(value=None): if value is None: return [] return value result = get_default() result.append(1) result2 = get_default() result2.append(2) print(result) # [1] print(result2) # [2] ``` [1] [2] # classmethod and staticmethod__call__ ```python class Parrotlet(object): size=15 def __init__(self,*,name='',color=''): self.name=name self.color=color def color(self): return self.color @staticmethod def talk(message): print(message) @classmethod def bar(clz,name,color): print("New parrotlet!",clz.__name__) parrot=Parrotlet(name=name,color=color) return parrot parrot1=Parrotlet(name='parrot1',color='green') parrot1.size parrot1.color parrot1.talk("Hello world") parrot2=parrot1.bar('parrot1','red') parrot2.talk("parrot2 talk") parrot2.size=20 # parrot2's attribute assert parrot2.size!=(parrot1.size==Parrotlet.size) Parrotlet.size=20 assert parrot2.size==parrot1.size==Parrotlet.size ``` 15 'green' Hello world New parrotlet! Parrotlet parrot2 talk # \__call\__ method ```python class Get_index(object): def __init__(self): pass def __call__(self,array,target): for index, item in enumerate(array): if item == target: yield index get_index=Get_index() print(*get_index([1,2,3,4,3,5,6],3)) ``` 2 4 # split ```python def concat(sp="/",*args,**kwargs): if args: return sp.join((str(i) for i in args)) if kwargs: for k in kwargs.keys(): print("{}{}{}".format(k,sep,kwargs[k])) return None concat2("~",hello="world",python="rocks") print(concat("/",*("G",100,"cm",))) print(concat("GGC","GCC")) #unpacking d={"hello":"world","python":"rocks"} print({**d}["python"]) # get d["python"] user={"name":"Trey",'website':"http://treyhunner.com"} defaults={'name':"Anonymous User",'page_name':"Profile page"} print({**defaults,**user}) # the default user name will be override print(concat("/",*("Hello python"))) ``` python~rocks hello~world G/100/cm GCC rocks {'name': 'Trey', 'page_name': 'Profile page', 'website': 'http://treyhunner.com'} H/e/l/l/o/ /p/y/t/h/o/n # bytes ```python print(b'python') """ Bytes 代表的是(二進位)數字的序列, 通過 ASCII 编碼之後才是我們看到的字符形式 """ print("print ascii number") print(b"Python"[0]) print(b"P"[0]) # print(b"嗨") # can only contain ASCII chacters ``` b'python' print ascii number 80 80 ```python print("print hex number when it is out of ascii range") # convert the word out of ASCII range(31-127) to hex number print(b'\xAF'[0]) print(b'\xaa'[0]) print(b'\xAB') ``` print hex number when it is out of ascii range 175 170 b'\xab' ```python print("convert number to ascii") # convert number to ascii print(bytes([24])) print(bytes([65,60,55])) print("convert hex to bytes") # convert hex to bytes print(bytes.fromhex("7A 7C")) print(b'ASCII'.hex()) print(int(b' '.hex(), base=16)) #have space ``` convert number to ascii b'\x18' b'A<7' convert hex to bytes b'z|' 4153434949 32 ```python # encode print("A".encode('ascii')) print("A".encode('ascii')[0])# find value in ascii # encode by unicode snake = '拉拉拉拉' try: snake.encode('ascii') except UnicodeEncodeError as err: print(err) # use UTF-8 print(snake.encode()) # utf-8 by default # bytearray is like byte "list",we can change it's # element but can't change byte's. ba=bytearray(b"Hello World") ba[0:1]=b"W" print(ba) ``` b'A' 65 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128) b'\xe6\x8b\x89\xe6\x8b\x89\xe6\x8b\x89\xe6\x8b\x89' bytearray(b'Wello World') ```python # bytes object b = b'example' # str object s = "example" # str to bytes bytes(s, encoding = "utf8") # bytes to str str(b, encoding = "utf-8") # an alternative method # str to bytes str.encode(s) # bytes to str bytes.decode(b) ``` 'example' ```python def convert_bytes_to_str(converted:bytes)->int: return bytes(converted).decode('utf-8') ``` ```python import json string=b'{"tmst":954473276,"time":"2017-06-26T15:52:55.802041+08:00","chan":5,"rfch":0,"freq":916.200000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5","lsnr":6.8,"rssi":-41,"size":15,"data":"QHhWNBKAEAAPyKqiGZ5W"}' json.loads(string.decode('utf-8')) ``` {'chan': 5, 'codr': '4/5', 'data': 'QHhWNBKAEAAPyKqiGZ5W', 'datr': 'SF7BW125', 'freq': 916.2, 'lsnr': 6.8, 'modu': 'LORA', 'rfch': 0, 'rssi': -41, 'size': 15, 'stat': 1, 'time': '2017-06-26T15:52:55.802041+08:00', 'tmst': 954473276} # context manager ```python from contextlib import contextmanager import logging def my_function(): logging.debug("Some debug data") logging.error("Error log here") logging.info("Info here") @contextmanager def debug_logging(level): logger=logging.getLogger() old_level=logger.getEffectiveLevel() logger.setLevel(level) try: yield finally: logger.setLevel(old_level) with debug_logging(logging.DEBUG): print("Inside:") my_function() print("After") my_function() ``` DEBUG:root:Some debug data ERROR:root:Error log here INFO:root:Info here ERROR:root:Error log here Inside: After ```python _G = {"counter": 99, "user": "admin"} class Refs(): def __init__(self, name = None): self.name = name self._G = _G self.init = self._G['counter'] def __enter__(self): return self def __exit__(self, *args): self._G["counter"] = self.init return False def acc(self, n = 1): self._G["counter"] += n def dec(self, n = 1): self._G["counter"] -= n def __str__(self): return "COUNTER #{name}: {counter}".format(**self._G, name=self.name) with Refs("ref1") as ref1, Refs("ref2") as ref2: for _ in range(3): ref1.dec() print(ref1) ref2.acc(2) print(ref2) print(_G) ``` COUNTER #ref1: 98 COUNTER #ref2: 100 COUNTER #ref1: 99 COUNTER #ref2: 101 COUNTER #ref1: 100 COUNTER #ref2: 102 {'user': 'admin', 'counter': 99} # Data and Time ```python from calendar import TextCalendar, HTMLCalendar # calendar tc=TextCalendar(firstweekday=6) tc.prmonth(2016,5) from datetime import date, time, datetime d1=date(2016,3,29) d2=date.today() d3=date.fromtimestamp(_time.time()) print(d1) print(d2) print(d3) ``` May 2016 Su Mo Tu We Th Fr Sa 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 2016-03-29 2017-06-21 2017-06-21 ```python # get month year day print("{}/{}/{}".format(d2.year,d2.month,d2.day)) #return struct_time struct,which can convert to tuple print("time.struct_time: {}".format(tuple(d2.timetuple()))) print("Monday is 0: {}\nMonday is 1: {}".format(d2.weekday(), d2.isoweekday())) ``` 2017/6/21 time.struct_time: (2017, 6, 21, 0, 0, 0, 2, 172, -1) Monday is 0: 2 Monday is 1: 3 ```python # Time t1 = time(22, 57, 6, 6) t2 = datetime.now().time() print(t1) print(t2) ``` 22:57:06.000006 18:33:00.607976 ```python # datetime.datetime dt1 = datetime(2016, 3, 30, 22, 2) dt2 = datetime.now() dt3 = datetime.fromtimestamp(_time.time()) print(dt1) print(dt2) print(dt3) ``` 2016-03-30 22:02:00 2017-06-21 18:33:15.273695 2017-06-21 18:33:15.273779 ```python # combine date and time dt = datetime.now() dt = datetime.fromtimestamp(_time.time()) d = dt.date() t = dt.time() print("Date: {}\nTime: {}".format(d, t)) print("Datetime: {}".format(datetime.combine(date.today(), time(2,3,3)))) ``` Date: 2017-06-21 Time: 18:34:31.443875 Datetime: 2017-06-21 02:03:03 ```python # count day from datetime import timedelta td = timedelta(weeks=1, days=2, hours=3,minutes=4, seconds=0, microseconds=0, milliseconds=0) print("Time duration: {}".format(td)) # minus current=datetime.now() today=datetime.combine(date.today(),time(0,0,0)) print("today: ",today) td=current-today print("{:.0f}s of Today".format(td.total_seconds())) today=date.today() lastyear=today.replace(year=today.year-1) print(today-lastyear) t1 = current.time() t2 = time(0, 0, 0) try: print(t1 - t2) except TypeError as err: print(err) # strftime & strptime print(datetime.strftime.__doc__) print(datetime.strptime.__doc__) fmat = "%y-%m-%d" dt = datetime.now() s = dt.strftime(fmat) print(s) print(datetime.strptime(s, fmat)) fmat = "%y/%-m/%-d" dt = datetime.now() dt = dt - timedelta(days=22) print(dt.strftime(fmat)) # or print("{}/{}/{}".format(dt.strftime("%y"), dt.month, dt.day)) ``` Time duration: 9 days, 3:04:00 today: 2017-06-21 00:00:00 67054s of Today 365 days, 0:00:00 unsupported operand type(s) for -: 'datetime.time' and 'datetime.time' format -> strftime() style string. string, format -> new datetime parsed from a string (like time.strptime()). 17-06-21 2017-06-21 00:00:00 17/5/30 17/5/30 # decorator ```python # decorator example def log(func): def wrapper(): print("INFO: Starting {}".format(func.__name__)) func() print("INFO: Finishing {}".format(func.__name__)) return wrapper @log def run(): print("Running run...") run() ``` INFO: Starting run Running run... INFO: Finishing run ```python class HTML(object): """ Baking HTML Tags! """ def __init__(self, tag="p"): print("LOG: Baking Tag <{}>!".format(tag)) self.tag = tag def __call__(self, func): return lambda: "<{0}>{1}</{0}>".format(self.tag, func(), self.tag) @HTML("html") @HTML("body") @HTML("div") def body(): return "Hello" print(body()) ``` LOG: Baking Tag <html>! LOG: Baking Tag <body>! LOG: Baking Tag <div>! <html><body><div>Hello</div></body></html> ```python # 傳遞參數 RULES = {} def route(rule): # rule is a string def decorator(hand): # hand is a function RULES.update({rule: hand}) # 填充到RULES裡面 return hand return decorator @route("/") def index(): print("Hello world!") def home(): print("Welcome Home!") # 將/home 和home()放進RULES home = route("/home")(home) index() home() print(RULES) # 印出RULES dict的內容 @route("/login") def login(user="user", pwd="pwd"): print("DB.findOne({{{}, {}}})".format(user, pwd)) login("hail", "python") print(RULES) ``` Hello world! Welcome Home! {'/home': <function home at 0x7fd11facaa60>, '/': <function index at 0x7fd11faca840>} DB.findOne({hail, python}) {'/home': <function home at 0x7fd11facaa60>, '/': <function index at 0x7fd11faca840>, '/login': <function login at 0x7fd11fa3f400>} ```python # sending paramerter def log(f): def wraper(*args, **kargs): print("INFO: Start Logging") f(*args, **kargs) print("INFO: Finish Logging") return wraper @log def run(hello="world"): print("Hello {}".format(hello)) run("Python2") ``` INFO: Start Logging Hello Python2 INFO: Finish Logging ```python from functools import update_wrapper """ functools.update_wrapper(wrapper, wrapped[, assigned][, updated]) """ class HTML(object): """ Baking HTML Tags! """ def __init__(self, tag="p"): print("LOG: Baking Tag <{}>!".format(tag)) self.tag = tag def __call__(self, func): def wraper(): return "<{0}>{1}</{0}>".format(self.tag, func(), self.tag) update_wrapper(wraper, func) return wraper @HTML("body") def body(): """ return body content! """ return "Hello, body!" print(body.__name__) print(body.__doc__) print(body()) ``` LOG: Baking Tag <body>! body return body content! <body>Hello, body!</body> ```python # 利用partial 修飾 from functools import update_wrapper, partial def my_wraps(wrapped): print(update_wrapper,wrapped) return partial(update_wrapper, wrapped=wrapped) def log(func): @my_wraps(func) def wraper(): print("INFO: Starting {}".format(func.__name__)) func() print("INFO: Finishing {}".format(func.__name__)) return wraper @log def run(): """ Docs' of run """ print("Running run...") print(run.__name__) print(run.__doc__) print(run()) ``` <function update_wrapper at 0x7fd1515ebd08> <function run at 0x7fd11fa84510> run Docs' of run INFO: Starting run Running run... INFO: Finishing run None # heap and queue ```python from heapq import heapify,heappop,heappush print(heapq.__all__) heap=[] heappush(heap,3) heappush(heap,2) heappush(heap,1) print(heap) # use heapify to turn list to heap heap=list(reversed(range(5))) print("List: ",heap) heapify(heap) print("Heap: ",heap) # heap 每次pop 出來的元素都會是最小的 heap=[2,3,4,1,2,4,6,7,11] heapify(heap) print(heappop(heap)) print(heappop(heap)) print(heappop(heap)) print(heappop(heap)) print(heap) ``` ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', 'nlargest', 'nsmallest', 'heappushpop'] [1, 3, 2] List: [4, 3, 2, 1, 0] Heap: [0, 1, 2, 4, 3] 1 2 2 3 [4, 6, 4, 7, 11] # queue ```python # queue.PriorityQueue from queue import PriorityQueue as PQueue pq=PQueue() pq.put((5*-1,'Python')) pq.put((4*-1,'C')) pq.put((4,'JS')) pq.put((3*-1,'Java')) pq.put((2*-1,'C++')) print('Inside PriorityQueue: ',pq.queue) while not pq.empty(): print(pq.get()[1]) ``` Inside PriorityQueue: [(-5, 'Python'), (-4, 'C'), (4, 'JS'), (-3, 'Java'), (-2, 'C++')] Python C Java C++ JS ```python # 經過list.sort()的list一定是heap 反之未必,只有經過heapify()的heap 才是heap # 而經過heappush()和heappop()都會對heap進行重新整理 import random from heapq import nlargest,nsmallest rand_list = [random.randrange(1, 100) for _ in range(5)] rand_list.sort() print("List: ", rand_list) print("Poped: ", heappop(rand_list)) heappush(rand_list, 4) print("Heap: ", rand_list) print("N largest: ",nlargest(10,heap)) print("N smallest: ",nsmallest(10,heap)) print(len(heap)) ``` List: [19, 37, 45, 83, 85] Poped: 19 Heap: [4, 37, 45, 85, 83] N largest: [11, 7, 6, 4, 4] N smallest: [4, 4, 6, 7, 11] 5 ```python # merge heap from heapq import merge heapA = sorted([random.randrange(1, 100) for _ in range(3)]) heapB = sorted([random.randrange(1, 100) for _ in range(3)]) print(heapA) print(heapB) merged = [] for i in merge(heapA, heapB): merged.append(i) print(merged) ``` [18, 61, 85] [14, 47, 75] [14, 18, 47, 61, 75, 85] ```python # heappushpop and heap replace from heapq import heapreplace,heappushpop lstA = [1,2,3,4,5] lstB = [1,2,3,4,5] poped = heapreplace(lstA, 0) print("lstA: ", lstA, "poped: ", poped) # pop and push poped = heappop(lstB) heappush(lstB, 0) print("lstB: ", lstA, "poped: ", poped) print("*"*30) poped = heappushpop(lstA, 9) print("lstA: ", lstA, "poped: ", poped) # is equal to... heappush(lstB, 9) poped = heappop(lstB) print("lstB: ", lstB, "poped: ", poped) ``` lstA: [0, 2, 3, 4, 5] poped: 1 lstB: [0, 2, 3, 4, 5] poped: 1 ****************************** lstA: [2, 4, 3, 9, 5] poped: 0 lstB: [2, 4, 3, 5, 9] poped: 0 # \__hash\__ and \__eq\__ ```python class Point: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, that): if not isinstance(that, Point): return False return self.x == that.x and self.y == that.y def __hash__(self): return 41 * (41 + self.x) + self.y p1 = Point(1, 1) p2 = Point(1, 1) pset = {p1} print(p2 in pset) class Point: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, that): if not isinstance(that, Point): return False return self.x == that.x and self.y == that.y class Point3D(Point): def __init__(self, x, y, z): super(Point3D, self).__init__(x, y) self.z = z def __eq__(self, that): if not isinstance(that, Point3D): return False return super(Point3D, self).__eq__(that) and self.z == that.z p1 = Point(1, 1) p2 = Point3D(1, 1, 1) print(p1 == p2) ``` True False # property ```python class Ball: def __init__(self, radius): if radius <= 0: raise ValueError('must be integer') self.__radius = radius def getRadius(self): return self.__radius def setRadius(self, radius): self.__radius = radius def delRadius(self): del self.__radius radius = property(getRadius, setRadius, delRadius, 'radius blablabla') ball=Ball(12) print (ball.radius) ball.radius=123 print (ball.radius) import math class Ball: def __init__(self, radius): if radius <= 0: raise ValueError('must be integer') self.__radius = radius @property def radius(self): return self.__radius @property def volumn(self): return 4.0 / 3.0 * math.pi * self.__radius ** 3 @volumn.setter def volumn(self, volumn): if volumn <= 0: raise ValueError('must be integer') self.__radius = ((3.0 * volumn) / (4.0 * math.pi)) ** (1.0 / 3.0) ball = Ball(10.0) print(ball.volumn) ball.volumn = 5000 print(ball.radius) ``` 12 123 4188.790204786391 10.60784417947055 # profile # sending email by python ```python import smtplib GMAIL_USER = 'EMAILADDRSS@gmail.com' GMAIL_PASS = 'PASSWORD' SMTP_SERVER = 'smtp.gmail.com' SMTP_PORT = 587 def send_email(recipient, subject, text): smtpserver = smtplib.SMTP(SMTP_SERVER,SMTP_PORT) smtpserver.ehlo() # smtpserver.starttls() # smtp.ehlo # smtpserver.login(GMAIL_USER, GMAIL_PASS) header = 'TO:' + recipient + '\n' + 'From:' + GMAIL_USER msg = header + '\n' + text +'\n\n' smtpserver.sendmail(GMAIL_USER, recipient, msg) smtpserver.close() ``` # shallow copy and deep copy ```python lst=[1,2,3] # copy list in four ways llst=[lst[:],lst,lst.copy(),[*lst]] print(id(lst)) print(llst[0] is lst) print(llst[1] is lst) print(llst[2] is lst) print(llst[3] is lst) for i,v in enumerate(llst): v.append("#{}".format(i)) print(lst) ``` 140245585483016 False True False False [1, 2, 3, '#1'] ```python d={"a":0} dd=[d,d.copy(),{**d}] for i,v in enumerate(dd): v['dd']="#{}".format(i) print(d) ``` {'dd': '#0', 'a': 0} ```python list_tmp=[1,3,4] llist=lst[:] llist.append("Wifi!!!!") print(list_tmp) ``` [1, 3, 4] ```python list_tmp=[1,3,4] llist=list_tmp llist.append("Wifi!!!!") print(list_tmp) ``` [1, 3, 4, 'Wifi!!!!'] ```python list_tmp=[1,3,4] llist=lst.copy() llist.append("Wifi!!!!") print(list_tmp) ``` [1, 3, 4] ```python list_tmp=[1,3,4] llist=[*[list_tmp]] llist.append("Wifi!!!!") print(list_tmp) ``` [1, 3, 4] ```python # shallow copy d={"a":{"b":[0]}} dd=[d,d.copy(),{**d}] print(dd[0] is d) print(dd[1] is d) print(dd[2] is d) ``` True False False ```python # deepcopy from copy import deepcopy # list lst=[0,1,[2,3]] lst2=deepcopy(lst) lst2[2].append(4) print(lst2) print(lst) # dict d={"a":{"b":[0]}} d2=deepcopy(d) d2["a"]["b"].append(1) print(d2) print(d) ``` [0, 1, [2, 3, 4]] [0, 1, [2, 3]] {'a': {'b': [0, 1]}} {'a': {'b': [0]}} # String format ```python print("{lang}.{suffix}".format(**{"lang":"Python","suffix":"py"})) print("{} {}".format(*["Python","C++"])) data={'name':'Python','score':100} print("Name:{0[name]}, Score:{0[score]}".format(data)) langs=["Hello","hello!"] print("{0[0]} vs {0[1]}".format(langs)) print("\n=======\nHelp(format):\n{.__doc__}".format(str.format)) ``` Python.py Python C++ Name:Python, Score:100 Hello vs hello! ======= Help(format): S.format(*args, **kwargs) -> str Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}'). ```python #可以通共!+r|s|a的方式對替換的變量進行轉換: #"{!r}"對變量調用repr() #"{!s}"對變量調用str() #"{!a}"對變量調用ascii() #align 代表方向 #fill為填充的字符(默認空白) for align, text in zip("<^>",["left","center","right"]): print("{:{fill}{align}16}".format(text, fill=align,align=align)) print("{:0=10}".format(100)) ``` left<<<<<<<<<<<< ^^^^^center^^^^^ >>>>>>>>>>>right 0000000100 ```python #強制顯示正負號 print("{0:+}\n{1:-}\n{0: }".format(3.14, -3.14)) ``` +3.14 -3.14 3.14 ```python # 用於表示特殊格式的(二進位to十進位)是否需要符號 print("Binary: {0:b}->{0:#b}".format(3)) ``` Binary: 11->0b11 ```python # 表示, print("Large Number: {0:}->{0:,}".format(1.25e5)) ``` Large Number: 125000.0->125,000.0 ```python # 0靠右對齊補0 print("Padding: {0:16}->{0:016}".format(3)) ``` Padding: 3->0000000000000003 ```python # 小數點格式優化 from math import pi print("pi={pi:.2},also={pi:.7}".format(pi=pi)) ``` pi=3.1,also=3.141593 ```python # Integer for t in "b c d #o #x #X n".split(): print("Type {0:>2} of {1} shows:{1:{t}}".format(t,97,t=t)) print("---------------------------------------------------------") ``` Type b of 97 shows:1100001 Type c of 97 shows:a Type d of 97 shows:97 Type #o of 97 shows:0o141 Type #x of 97 shows:0x61 Type #X of 97 shows:0X61 Type n of 97 shows:97 --------------------------------------------------------- ```python # Float for t,n in zip("eEfFgGn%",[1234,123,2.3,22.11,1,2,3.1415,0.98886]): print("Type {} shows:{:.2{t}}".format(t,n,t=t)) ``` Type e shows:1.23e+03 Type E shows:1.23E+02 Type f shows:2.30 Type F shows:22.11 Type g shows:1 Type G shows:2 Type n shows:3.1 Type % shows:98.89% ```python # string # 如果數字要印出來不用+s try: print("{:s}".format(1234555)) except: print("{}".format(12345)) ``` --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-51-15f35bbfb6a3> in <module>() 2 # 如果數字要印出來不用+s 3 ----> 4 print("{:s}".format(1234555)) ValueError: Unknown format code 's' for object of type 'int' ```python ``` ## String functions ```python hello = [i.upper()for i in 'hello'] s = u'你好' print(s) print(len(s)) print(s.encode()) ``` 你好 2 b'\xe4\xbd\xa0\xe5\xa5\xbd' ```python """ unicode common func """ str1 = "Hello World" print(",".join(str1.split())) print("http://www.google.com".split("/", 2)) # 限定切分切兩次 str2 = "coffee" print(str2.find('f')) print(str2.index('f')) # where the index is print(str2.rfind('f')) # find from right print(str2.find('a')) print(str2.rfind('a')) # print(str2.index('a')) # if not in substring than raise ValueError ``` Hello,World ['http:', '', 'www.google.com'] 2 2 3 -1 -1 ```python """ stripe """ print(" hello world ".strip()) print("helloworld".strip("heo")) print("[" + " i ".lstrip() + "]") print("[" + " i ".rstrip() + "]") print("[" + " i ".strip() + "]") print("{}\n{}\n{}\n{}\n{}".format( "hello, WORLD".upper(), "hello, WORLD".lower(), "hello, WORLD".swapcase(), "hello, WORLD".capitalize(), "hello, WORLD".title())) ``` hello world lloworld [i ] [ i] [i] HELLO, WORLD hello, world HELLO, world Hello, world Hello, World ```python print(""" {}|{} {}|{} {}|{} {}|{} {}|{} {}|{} """.format( "Python".startswith("P"), "Python".startswith("y"), "Python".endswith("n"), "Python".endswith("o"), "i23o6".isalnum(), "1 2 3 0 6".isalnum(), "isalpha".isalpha(), "isa1pha".isalpha(), "python".islower(), "Python".islower(), "PYTHON".isupper(), "Python".isupper(), )) print("HIHI".zfill(8)) # 回傳以 0 塞滿 width 的新字串 ``` True|False True|False True|False True|False True|False True|False 0000HIHI # sorted ```python #Python 提供兩種排序方法,一種是針對List的原地排序list.sort()另一個是針對所有可迭代對象的sorted() from random import randrange lst=[randrange(1,100) for _ in range(10)] print(lst) lst.sort() print(lst) ``` [16, 73, 80, 49, 30, 57, 19, 38, 80, 53] [16, 19, 30, 38, 49, 53, 57, 73, 80, 80] ```python #sorted() 不限於list,且會生成一個新的排序後的list,原有對象不受影響 lst=[randrange(1,100) for _ in range(10)] tup=tuple(lst) print(sorted(lst)) print(tup) print(sorted(tup)) ``` [4, 25, 58, 65, 66, 67, 72, 76, 89, 94] (72, 58, 67, 4, 65, 89, 76, 66, 94, 25) [4, 25, 58, 65, 66, 67, 72, 76, 89, 94] ```python #透過key 指定排序 lst2=[randrange(1,100) for _ in range(10)] print(lst2) print(sorted(lst2,key=abs)) # 透過絕對值進行排序 ``` [93, 36, 9, 67, 86, 55, 19, 23, 30, 84] [9, 19, 23, 30, 36, 55, 67, 84, 86, 93] ```python # 當迭代對象教複雜時 可以只按照其中的某些屬性進行排序 lst3=list(zip("Today is a good day,so I have to go to school.".split(),[randrange(1,10) for _ in range(13)])) print(lst3) print(sorted(lst3,key=lambda item:item[1])) # 透過key進行排序(可改0) ``` [('Today', 3), ('is', 3), ('a', 4), ('good', 6), ('day,so', 3), ('I', 3), ('have', 3), ('to', 7), ('go', 1), ('to', 8), ('school.', 1)] [('go', 1), ('school.', 1), ('Today', 3), ('is', 3), ('day,so', 3), ('I', 3), ('have', 3), ('a', 4), ('good', 6), ('to', 7), ('to', 8)] ```python # 可以過operator 獲取元素的屬性 from operator import itemgetter, attrgetter print("-"*20) print(sorted(lst3, key=itemgetter(1))) ``` -------------------- [('go', 1), ('school.', 1), ('Today', 3), ('is', 3), ('day,so', 3), ('I', 3), ('have', 3), ('a', 4), ('good', 6), ('to', 7), ('to', 8)] ```python # 和lambda item:item[1]))作用相同 fitemgetter=lambda ind:lambda item: item[ind] print(sorted(lst3,key=fitemgetter(1))) class P(object): def __init__(self, w, n): self.w=w self.n=n def __repr__(self): return "{}=>{}".format(self.w, self.n) ps=[P(i[0],i[1]) for i in lst3] print(sorted(ps,key=attrgetter('n'))) ``` [('go', 1), ('school.', 1), ('Today', 3), ('is', 3), ('day,so', 3), ('I', 3), ('have', 3), ('a', 4), ('good', 6), ('to', 7), ('to', 8)] [go=>1, school.=>1, Today=>3, is=>3, day,so=>3, I=>3, have=>3, a=>4, good=>6, to=>7, to=>8] ```python # python3 cmp using from functools import cmp_to_key as new_cmp_to_key #new_cmp_to_key work like this def cmp_to_key(mycmp): # convert a cmp= function into a kye= function class K: def __init__(self,obj,*args): self.obj=obj def __lt__(self, other): return mycmp(self.obj, other.obj) return K def reverse_cmp(x, y): return y[1]-x[1] print(sorted(lst3,key=cmp_to_key(reverse_cmp))) ``` [('to', 8), ('go', 1), ('school.', 1), ('to', 7), ('good', 6), ('a', 4), ('Today', 3), ('is', 3), ('day,so', 3), ('I', 3), ('have', 3)] # testdoc ```python """ This is the "example" module. The example module supplies one function, factorial(). For example, >>> factorial(5) 120 """ def factorial(n): """Return the factorial of n, an exact integer >= 0. If the result is small enough to fit in an int, return an int. Else return a long. >>> [factorial(n) for n in range(6)] [1, 1, 2, 6, 24, 120] >>> [factorial(long(n)) for n in range(6)] [1, 1, 2, 6, 24, 120] >>> factorial(30) 265252859812191058636308480000000L >>> factorial(30L) 265252859812191058636308480000000L >>> factorial(-1) Traceback (most recent call last): ... ValueError: n must be >= 0 Factorials of floats are OK, but the float must be an exact integer: >>> factorial(30.1) Traceback (most recent call last): ... ValueError: n must be exact integer >>> factorial(30.0) 265252859812191058636308480000000L It must also not be ridiculously large: >>> factorial(1e100) Traceback (most recent call last): ... OverflowError: n too large """ import math if not n >= 0: raise ValueError("n must be >= 0") if math.floor(n) != n: raise ValueError("n must be exact integer") if n+1 == n: # catch a value like 1e300 raise OverflowError("n too large") result = 1 factor = 2 while factor <= n: result *= factor factor += 1 return result if __name__ == "__main__": import doctest doctest.testmod() ``` ********************************************************************** File "__main__", line 18, in __main__.factorial Failed example: [factorial(long(n)) for n in range(6)] Exception raised: Traceback (most recent call last): File "/usr/lib/python3.5/doctest.py", line 1321, in __run compileflags, 1), test.globs) File "<doctest __main__.factorial[1]>", line 1, in <module> [factorial(long(n)) for n in range(6)] File "<doctest __main__.factorial[1]>", line 1, in <listcomp> [factorial(long(n)) for n in range(6)] NameError: name 'long' is not defined ********************************************************************** File "__main__", line 20, in __main__.factorial Failed example: factorial(30) Expected: 265252859812191058636308480000000L Got: 265252859812191058636308480000000 ********************************************************************** File "__main__", line 22, in __main__.factorial Failed example: factorial(30L) Exception raised: Traceback (most recent call last): File "/usr/lib/python3.5/doctest.py", line 1321, in __run compileflags, 1), test.globs) File "<doctest __main__.factorial[3]>", line 1 factorial(30L) ^ SyntaxError: invalid syntax ********************************************************************** File "__main__", line 34, in __main__.factorial Failed example: factorial(30.0) Expected: 265252859812191058636308480000000L Got: 265252859812191058636308480000000 ********************************************************************** 1 items had failures: 4 of 8 in __main__.factorial ***Test Failed*** 4 failures. # signal ```python import signal,functools import time class TimeoutError(Exception): pass def timeout(seconds, error_message = 'Function call timed out'): def decorated(func): def _handle_timeout(signum, frame): raise TimeoutError(error_message) def wrapper(*args, **kwargs): signal.signal(signal.SIGALRM, _handle_timeout) signal.alarm(seconds) try: result = func(*args, **kwargs) finally: signal.alarm(0) return result return functools.wraps(func)(wrapper) return decorated @timeout(10,"hello world!") def loop(): while(1): time.sleep(5) loop() ``` --------------------------------------------------------------------------- TimeoutError Traceback (most recent call last) <ipython-input-73-6e8efc94b623> in <module>() 22 while(1): 23 time.sleep(5) ---> 24 loop() <ipython-input-73-6e8efc94b623> in wrapper(*args, **kwargs) 11 signal.alarm(seconds) 12 try: ---> 13 result = func(*args, **kwargs) 14 finally: 15 signal.alarm(0) <ipython-input-73-6e8efc94b623> in loop() 21 def loop(): 22 while(1): ---> 23 time.sleep(5) 24 loop() <ipython-input-73-6e8efc94b623> in _handle_timeout(signum, frame) 6 def decorated(func): 7 def _handle_timeout(signum, frame): ----> 8 raise TimeoutError(error_message) 9 def wrapper(*args, **kwargs): 10 signal.signal(signal.SIGALRM, _handle_timeout) TimeoutError: hello world!