python 之金玉良言 或許是最後一次給本身系統總結--已結

jar tvf xxx.jar
vim xxx.jar (其實 底層調用 unzip , zip 命令)html

配置一下 notepad++ F5
cmd /k D:"Program Files (x86)"\python\python.exe "$(FULL_CURRENT_PATH)" &pause &exitjava

# 查看已經鏈接過的 wifi 密碼
for /f "skip=9 tokens=1,2 delims=:" %i in ('netsh wlan show profiles') do @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear
進入 venv 生成 requirements.txt
pip freeze > requirements.txt
pip install -r requirements.txt

python 多重繼承之拓撲排序python

關鍵字:  DAG 有向無環圖 , 最左原則 實現 MRO (method resolution order) 方法解析順序 之繼承鏈

定製類git

java 說我仍是不太相信你,仍是給你定一個規範吧, python 說 你是個成年人了,你知道爲你的代碼負責

不要對實例屬性和類屬性使用相同的名字,不然將產生難以發現的錯誤。實力屬性老是會覆蓋 類屬型
getattr()、setattr()以及hasattr() ,dir() 內省

map filter 爲 iter惰性計算的 Iterator, reduce 跟sorted 倒是 當即計算

模塊搜索路徑
當咱們試圖加載一個模塊時,Python會在指定的路徑下搜索對應的.py文件,若是找不到,就會報錯:


try:#python2
    from UserDict import UserDict
    #建議按照python3的名字進行import
    from UserDict import DictMixin as MutableMapping
except ImportError:#python3
    from collections import UserDict
    from collections import MutableMapping

>>> import mymodule
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named mymodule
默認狀況下,Python解釋器會搜索當前目錄、全部已安裝的內置模塊和第三方模塊,搜索路徑存放在sys模塊的path變量中:

>>> import sys
>>> sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', ..., '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
若是咱們要添加本身的搜索目錄,有兩種方法:

一是直接修改sys.path,添加要搜索的目錄:

>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
這種方法是在運行時修改,運行結束後失效。

第二種方法是設置環境變量PYTHONPATH,該環境變量的內容會被自動添加到模塊搜索路徑中。設置方式與設置Path環境變量相似。注意只須要添加你本身的搜索路徑,Python本身自己的搜索路徑不受影響。


set和dict的惟一區別僅在於沒有存儲對應的value,可是,set的原理和dict同樣,因此,一樣不能夠放入可變對象,由於沒法判斷兩個可變對象是否相等,也就沒法保證set內部「不會有重複元素」。

請務必注意,dict內部存放的順序和key放入的順序是沒有關係的。

和list比較,dict有如下幾個特色:

查找和插入的速度極快,不會隨着key的增長而變慢;
須要佔用大量的內存,內存浪費多。
而list相反:

查找和插入的時間隨着元素的增長而增長;
佔用空間小,浪費內存不多。
因此,dict是用空間來換取時間的一種方法。

dict能夠用在須要高速查找的不少地方,在Python代碼中幾乎無處不在,正確使用dict很是重要,須要牢記的第一條就是dict的key必須是不可變對象。

這是由於dict根據key來計算value的存儲位置,若是每次計算相同的key得出的結果不一樣,那dict內部就徹底混亂了。這個經過key計算位置的算法稱爲哈希算法(Hash)。

要保證hash的正確性,做爲key的對象就不能變。在Python中,字符串、整數等都是不可變的,所以,能夠放心地做爲key。而list是可變的,就不能做爲key:

>>> key = [1, 2, 3]
>>> d[key] = 'a list'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'



l = [4,5,6]
t = (1,)
s = {1}
# s = set([1,2,3])
d = {'name':'frank'}

help(abs)


把函數做爲參數傳入,這樣的函數稱爲高階函數,函數式編程就是指這種高度抽象的編程範式。


from functools import reduce
import re
exp = '99 + 88 + 7.6 ='
reduce(lambda x,y:float(x)+float(y),
       filter(lambda x:True if x else False,
              map(lambda x:x.strip(),
                  re.split(r'[\+=]',exp))))



爲何要設計str、None這樣的不變對象呢?由於不變對象一旦建立,對象內部的數據就不能修改,這樣就減小了因爲修改數據致使的錯誤。此外,因爲對象不變,多任務環境下同時讀取對象不須要加鎖,同時讀一點問題都沒有。咱們在編寫程序時,若是能夠設計一個不變對象,那就儘可能設計成不變對象。

凡是可做用於for循環的對象都是Iterable類型;

凡是可做用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

集合數據類型如list、dict、str等是Iterable但不是Iterator,不過能夠經過iter()函數得到一個Iterator對象。

Python的for循環本質上就是經過不斷調用next()函數實現的,例如:

for x in [1, 2, 3, 4, 5]:
    pass
實際上徹底等價於:

# 首先得到Iterator對象:
it = iter([1, 2, 3, 4, 5])
# 循環:
while True:
    try:
        # 得到下一個值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循環
        break
"""
練習
小明身高1.75,體重80.5kg。請根據BMI公式(體重除以身高的平方)幫小明計算他的BMI指數,並根據BMI指數:

低於18.5:太輕
18.5-25:正常
25-28:太重
28-32:肥胖
高於32:嚴重肥胖
"""
height = 1.75
weight = 80.5

def BMI(height,weight):
    bmi = (weight/height)**2
    results = ("太輕","正常","太重","肥胖","嚴重肥胖")
    ret = results[-1]
    if bmi<18.5:
        ret = results[0]
    elif 18.5<=bmi<25:
        ret = results[1]
    elif 25<=bmi<28:
        ret = results[2]
    elif 28<=bmi<32:
        ret = results[3]
    else:
        pass
    return ret

BMI(height,weight)

    

def myhex(num):
    
    hex_list = []
    t_mt = ('A','B','C','D','E','F')
    while True:
        mod_, num = num %16, num//16
        hex_list.append(t_mt[mod_-10]) if mod_>9 else hex_list.append(str(mod_))
        if num== 0 :
            break
    hex_list.append('0x')
    hex_list.reverse()
    return ''.join(hex_list)

myhex(25)

def my_octonary(num):
    octonary_list = []
    while True:
        mod_,num = num%8,num//8
        octonary_list.append(str(mod_))
        if num == 0:
            break
    octonary_list.append('0o')
    octonary_list.reverse()
    return ''.join(octonary_list)
    
my_octonary(9)

# 基本遞歸
def fac(n):
    if n>1:
        return n*fac(n-1)
    elif n==1:
        return 1
    else:
        raise ValueError('數值必須大於等於1')

# 尾遞歸方式
def fac_iter(num,product):
    if num==1:
        return product
    else:
        return fac_iter(num-1,num*product)
    
# 循環實現
def fac2(n):
    if n<1:
        raise ValueError('數值必須大於等於1')
    acc = 1
    while n>=1:
        acc*=n
        n-=1
    return acc

fac_iter(4,1)

str2float

# -*- coding: utf-8 -*-
from functools import reduce
digital_dict = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
def str2float(s):
    i,j = s.split('.')
    left = reduce(lambda x,y:x*10+y,map(lambda x:digital_dict.get(x),i))
    right = reduce(lambda x,y:x/10+y,list(map(lambda x:digital_dict.get(x),j))[::-1])/10
    return left+right

str2float('123.456')

累乘

# -*- coding: utf-8 -*-
from functools import reduce
def prod(L):
    return reduce(lambda x,y:x*y,L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
if prod([3, 5, 7, 9]) == 945:
    print('測試成功!')
else:
    print('測試失敗!')

名字這個我改了測試

names = ['adam', 'LISA', 'barT']

def normalize(names):
    return list(map(lambda name:str.upper(name[0])+str.lower(name[1:]),names))

# normalize(names)
# 測試:
L1 = ['adam', 'LISA', 'barT']
L2 = normalize(L1)
print(L2)

str2int

digital_dict = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
from functools import reduce

def str2int(s):
    return reduce(lambda x,y:x*10+y,map(lambda x:digital_dict.get(x),s))
str2int('13579')


def _odd_iter():
    n = 1
    while True:
        n = n + 2
        yield n
        
def _not_divisible(n):
    return lambda x: x % n > 0

def primes():
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一個數
        yield n
        it = filter(_not_divisible(n), it) # 構造新序列
        
# 打印1000之內的素數:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break


def _odd_iter3():
    n = 3
    while True:
        yield n
        n+=2
     
def _not_divisible_3(n):
    return lambda x:x%n>0

def prime_iter3():
    yield 2
    it = _odd_iter()
    
    while True:
        base_num = next(it)
        yield base_num
        it = filter(lambda x,y=base_num:x%y>0,it)
        
for i in prime_iter3():
    if i>50:
        break
    else:
        print(i,end=',')


# -*- coding: utf-8 -*-

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

def by_score(x):
    return x[1]

def by_name(x):
    return x[0]

sorted(L,key=by_score,reverse=True)
sorted(L,key=by_name,reverse=True)


def createCounter():
    count = 0
    def counter():
        nonlocal count 
        count += 1
        return count
    return counter

def createCounter():
    def f():
        n=1 
        while True:
            yield n
            n +=1
    g=f()
    def counter():
        return next(g)
    return counter

# 測試:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('測試經過!')
else:
    print('測試失敗!')

def createCounter():
    x = 0
    def counter():
        nonlocal x
        x += 1
        return x
    return counter


from collections import Counter
Counter(s=3, c=2, e=1, u=1)
Counter({'s': 3, 'c': 2, 'u': 1, 'e': 1})
some_data=('c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd')
Counter(some_data).most_common(2)
[('d', 3), ('c', 2)]
some_data=['c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd']
Counter(some_data).most_common(2)
[('d', 3), ('c', 2)]
some_data={'c', '2', 2, 3, 5, 'c', 'd', 4, 5, 'd', 'd'}
Counter(some_data).most_common(2)
[('c', 1), (3, 1)]
class Fib():
    
    # 構造方法
    def __init__(self,a=0,b=1):
        self.__a,self.__b = a,b
    
    def __enter__(self):
        print('Begin')
        # 這裏 實際能夠新增 打開資源動做
        return self
        
    def __exit__(self,exc_type,exc_value,traceback):
        if exc_type:
            print('Error')
        else:
            print('End')
            
    #生成器 1
    def __iter__(self):
        return self
    
    # 生成器 2
    def __next__(self):
        self.__a, self.__b = self.__b, self.__a + self.__b
        
        if self.__a >10:
            raise StopIteration()
        
        return self.__a
    
    def __generatorfib(self,start,stop):
        x, y = 1,1
        print(start,'-->',stop)
        begin = int(start)
        end = int(stop)
        while begin<=end:
                yield x
                x, y = y,x+y
                begin, end = begin+1,end-1
        

    # 作成可下標取
    def __getitem__(self,n):
        if isinstance(n,int):
            x, y = 1,1
            for i in range(n):
                x, y = y,x+y
            return x
        
        # 下面這個沒有真正支持 step
        if isinstance(n,slice):
            start = n.start if n.start else 0
            stop = n.stop
            step = n.step
            x,y = 1,1
            L = []
            for n in range(0,stop,step):
                if n>=start:
                    L.append(x)
                x, y = y,x+y
            return L[start:stop:step]
        
#         if isinstance(n,slice):
#             start = slice.start
#             stop = slice.stop
#             step = slice.step
#             inner_fib = self.__generatorfib(start,stop)
#             L = list(inner_fib)
#             return L[start,stop,step]
            
    def __getattr__(self,attr):
        if attr=='age':
            return lambda :18
        raise AttributeError('\'Fib\' object has no attribute \'{}\''.format(attr))
    
    # 打印給 user 看
    def __str__(self):
        return 'Fib({},{})'.format(self.__a,self.__b)
    
    # 打印給程序員看
    def __repr__(self):
        return self.__str__()
    # 重複聲明一次是多餘的可是指出這種用法
    __repr__ = __str__
    
for n in eval('Fib(0,1)'):
    print(n,end=',')
    
with Fib() as f:
    f[0:5:1]
    f.age()
    f.score()

元類 暫時學到這兒 ,產生 class 對象的 模板 必須繼承自 type , 先有類來後有天,元類更在類以前, python 的 動態特性簡直如此憨直 動到極致

class Field(object):
    
    def __init__(self,name,column_type):
        self.name = name
        self.column_type = column_type
        
    def __str__(self):
        return 'Field({name},{column_type})'.format(name=self.name,column_type=self.column_type)
    
    __repr__ = __str__
    
class IntegerField(Field):
    
    def __init__(self,name):
        super(IntegerField,self).__init__(name,'bigint')
        
class VarcharField(Field):
    
    def __init__(self,name):
        super(VarcharField,self).__init__(name,'varchar(256)')
        
class ModelMetaclass_frank(type):
    
    def __new__(cls,name,bases,attrs):
        if name=='Model':
            return type.__new__(cls,name,bases,attrs)
        print('found sub-model: {sub_model}'.format(sub_model=name))
        
        #準備一個 object 屬性 與 列關係映射
        mappings = {}
        # 遍歷 類屬性僅 將 instance 爲 Field  的 添加到 mappings 裏保存起來
        for attr_key,attr_value in attrs.items(): 
            # attr_value ==》 
            if isinstance(attr_value,Field):
                print('Found mapping: {}==>{}'.format(attr_key,attr_value))
                mappings[attr_key] = attr_value
        
        # 去除掉 attr (類屬性) 中 有的,可是 mappings(能夠看做是 實例屬性 這裏有點繞 這裏的 實例是 type 建立出來的 class 實例) 中也有的 屬性 ,避免 屬性覆蓋
        for instance_key in mappings.keys():
            attrs.pop(instance_key)
            
        # 將保存好的  實例屬性 以及 table 名字 保留到 attr 中
        attrs['__mappings__'] = mappings
        attrs['__table__'] = str.lower(name)  # 這裏的 那麼 徹底能夠改成 xxx_+ name  好比 訂單 register_user ,login_user
        return type.__new__(cls,name,bases,attrs)
    
class Model(dict,metaclass=ModelMetaclass_frank):
    
    def __init__(self,*args,**kw):
        super(Model, self).__init__(*args,**kw)

    def __getattr__(self,key):
        try:
            value = self.get(key)
        except KeyError as e:
            raise AttributeError(r'"Model" object has no attribute "{}"'.format(key))
        return value
#     def __setattr__(self,key,value):
#         self[key] = value
    
    def  save(self):
        fields = []
        params = []
        args = []
        
        for instance_attr_key,instance_attr_value in self.__mappings__.items():
            fields.append(instance_attr_value.name) # 這裏是 Field 類中的 self.name
            params.append('?')
#             print('-->',getattr(self,instance_attr_key,None))
#             args.append(getattr(self,instance_attr_key,None))
            args.append(self.__getattr__(instance_attr_key))
            
        print('fiels: --> ',','.join(fields))
        print('params: -->',','.join(params))
        print('args: -->',args)
        args = list(map(lambda s: '\''+s+'\'' if isinstance(s,str) else str(s),args))
        sql = 'insert into {table_name}({fields_str}) values({values})'.format(table_name=self.__table__,fields_str=','.join(fields),values=','.join(args))
        print(sql)
        

class User(Model):
    # 定義類的屬性到列的映射:
    id = IntegerField('id')
    name = VarcharField('username')
    email = VarcharField('email')
    password = VarcharField('password')

# 建立一個實例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
u.save()
class Field(object):
    
    def __init__(self,name,column_type):
        self.name = name
        self.column_type = column_type
        
    def __str__(self):
        return ''.format(name=self.name,column_type=self.column_type)
        
class IntegerField(Field):
    
    def __init__(self,name):
        super(IntegerField,self).__init__(name,'bigint')
        
class StringField(Field):
    
    def __init__(self,name):
        return super(StringField,self).__init__(name,'varchar(256)')
    
# 元類必須繼承自 type
class ModelMetaclass(type):
    
    def __init__(self,*args,**kw):
        return super(ModelMetaclass,self).__init__(*args,**kw)
    
    def __new__(cls,name,bases,attrs):
        print(cls,'<-->',name)
        if name=='Model':
            return type.__new__(cls,name,bases,attrs)
        print('Founding sub-model {sub_model}'.format(sub_model=name))
        
        mappings = {}
        for k,v in attrs.items():
            if isinstance(v,Field):
                mappings[k] = v
                
        for k in mappings.keys():
            attrs.pop(k)
            
        attrs['__mappings__'] = mappings
        attrs['__table__'] = attrs.get('__table__',str.lower(name))
        return type.__new__(cls,name,bases,attrs)
    
class Model(dict,metaclass=ModelMetaclass):
    
    def __init__(self,*args,**kw):
        super(Model,self).__init__(*args,**kw)
        
    def __getattr__(self,key):
        try:
            value = self.get(key)
        except KeyError:
            raise('\'{object}\' has no attr \'{attr}\''.format(object=self.__name__,attr=key))
        return value
        
    def save(self):
        fields = []
        args = []
        
        for k,v in self.__mappings__.items():
            fields.append(v.name)
            args.append(self.__getattr__(k))
            
        field_list = ','.join(fields)
        arg_list = ','.join(list(map(lambda x: '\'{}\''.format(x) if isinstance(x,str) else str(x),args)))
        sql = 'insert into {table_name}({field_list}) values({arg_list})'.format(table_name=self.__table__,field_list=field_list,arg_list=arg_list)
        print(sql)
        
        
class LoginUser(Model):
    id = IntegerField('id')
    name = StringField('name')
    email = StringField('email')
    password = StringField('password')
    
    __table__ = 'loginuser'
    
class RegisterUser(Model):
    id = IntegerField('id')
    name = StringField('name')
    email = StringField('email')
    password = StringField('password')
    
    __table__ = 'registeruser'
    

login_user = LoginUser(id=1,name='Frank',email='frank@whatever.com',password='passwordxxx')
login_user.save()

    
    
register_user = RegisterUser(id=1,name='Frank',email='frank@whatever.com',password='passwordxxx')
register_user.save()

內建模塊

# datetime
from datetime import datetime,timedelta

now = datetime.now()

# datetime 轉 timestamp
now_timestamp = now.timestamp()

# timestampe 轉本地 datetime
dt_local = datetime.fromtimestamp(now_timestamp)
# timestampe 轉utc datetime
dt_utc = datetime.utcfromtimestamp(now_timestamp)

# 時間戳 沒有時區, datetime中攜帶
print(dt_local.timestamp(),'<-->',dt_utc.timestamp())

print('{}\n{}\n{}\n{}'.format(now,now_timestamp,dt_local,dt_utc))
# 獲取指定 日期和時間
year = 2019
month =3
day =3
hour = 15
minute = 7
dt_specified = datetime(year,month,day,hour,minute)
print(dt_specified)

# str 轉 datetime  str parse
datetime_str = '2019-03-03 15:22:00'
datetime_parse_format = '%Y-%m-%d %H:%M:%S'
cday = datetime.strptime(datetime_str,datetime_parse_format)
print(cday)

# datetime 轉 str  str format
print(cday.strftime('%Y/%m/%d'))

# 日期變化(delta) 用 timedelta
now = datetime.now()
now_next3_hours =  now+timedelta(hours=3)
now_previous3_days = now+timedelta(days=-3)
print('next 3 hours: {}'.format(now_next3_hours))

print('now_previous3_days: {}'.format(now_previous3_days))

from datetime import timezone

tz_utc_8 = timezone(timedelta(hours=8))
now = datetime.now()
# 一開始 now 時區信息爲 None
print(now.tzinfo)
# 暴力設置一個時區
now.replace(tzinfo=tz_utc_8)
print(now)

utc_now = datetime.utcnow()
# 一開始這玩意兒壓根木有時區信息啊
print(utc_now.tzinfo)
# 暴力設置時區信息
utc_now = utc_now.replace(tzinfo=timezone.utc)

#北京日期時間 東八區
bj_dt = utc_now.astimezone(timezone(timedelta(hours=8)))
# 西八區
pst_dt = utc_now.astimezone(timezone(timedelta(hours=-8)))
# 東 9 區
tokyo_dt = utc_now.astimezone(timezone(timedelta(hours=9)))

print('bj_dt: ',bj_dt)
print('pst_dt: ',pst_dt)
print('tokyo_dt: ',tokyo_dt)



from datetime import datetime, timezone,timedelta
import re

def to_timestamp(dt_str,tz_str):
    re_dt_str_1 = r'\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}'
    
    re_tz_str = r'^UTC([+-])(\d{1,2}):\d{2}$'
    
    tz_grps = re.match(re_tz_str,tz_str).groups()
    
    sign = tz_grps[0]
    hours = int(tz_grps[1])
    
    if re.match(re_dt_str_1,dt_str):
        dt = datetime.strptime(dt_str,'%Y-%m-%d %H:%M:%S')
        if sign=='+':
            tz_info_x = timezone(timedelta(hours=hours))
        else:
            tz_info_x = timezone(timedelta(hours=-hours))
        dt = dt.replace(tzinfo=tz_info_x)
    else:
        print('re is wrong!')
        
    return dt.timestamp()

# 測試:
t1 = to_timestamp('2015-6-1 08:10:30', 'UTC+7:00')

assert t1 == 1433121030.0, t1

t2 = to_timestamp('2015-5-31 16:10:30', 'UTC-09:00')
assert t2 == 1433121030.0, t2

print('ok')

collections 模塊

def chunks(l, n):
    return [l[i:i+n] for i in range(0, len(l), n)]

chunks(s,2)

from collections import Iterator, Iterable
from collections import defaultdict
from collections import Counter, ChainMap, OrderedDict, namedtuple, deque
from itertools import islice  #  替代 切片,可是隻能 是正數
from itertools import zip_longest # 替代 zip 能夠 對不同個數的 進行迭代

from concurrent.futures import ThreadPoolExecutor as Pool


from collections import namedtuple, deque, defaultdict, OrderedDict, ChainMap, Counter

Point = namedtuple('Poing',['x','y','z'])
p = Point(1,2,3)
print(p.x,'--',p.y,'--',p.z)

# 雙向列表
dq = deque([1,2,3,4])
dq.append(5)
dq.appendleft('a')
dq.popleft()

default_dict = defaultdict(lambda:'N/A') # 多了一個默認值
default_dict['name']='frank'
default_dict['age']

od = OrderedDict([('b',1),('a',2),('c',3)]) # 按照插入的順序有序
od.get('a')


# 能夠實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最先添加的Key
from collections import OrderedDict

class LastUpdatedOrderedDict(OrderedDict):

    def __init__(self, capacity):
        super(LastUpdatedOrderedDict, self).__init__()
        self._capacity = capacity

    def __setitem__(self, key, value):
        containsKey = 1 if key in self else 0
        if len(self) - containsKey >= self._capacity:
            last = self.popitem(last=False)
            print('remove:', last)
        if containsKey:
            del self[key]
            print('set:', (key, value))
        else:
            print('add:', (key, value))
        OrderedDict.__setitem__(self, key, value)


# 應用場景 設置參數優先級
from collections import ChainMap
import os, argparse

# 構造缺省參數:
defaults = {
    'color': 'red',
    'user': 'guest'
}

# 構造命令行參數:
parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
namespace = parser.parse_args()
command_line_args = { k: v for k, v in vars(namespace).items() if v }

# 組合成ChainMap:
combined = ChainMap(command_line_args, os.environ, defaults)

# 打印參數:
print('color=%s' % combined['color'])
print('user=%s' % combined['user'])

c = Counter()
for ch in 'programing':
    c[ch] +=1

print(c)

c = dict()
for ch in 'programing':
    if ch in c:
        c[ch] +=1
    else:
        c[ch] = 1


給單詞按首字母分組
方法一:
words = ['apple','bat','bar','atom','book'] 
by_letter_grp_dict = {}
for word in words:
    letter = word[0]
    if letter in by_letter_grp_dict:
        by_letter_grp_dict[letter].append(word)
    else:
        by_letter_grp_dict[letter] = [word]
print(by_letter_grp_dict)
方法二:
內置的collections模塊有一個叫作defaultdict的類,它可使該過程更簡單。傳入一個類型或函數(用於生成字典各插槽所使用的默認值)便可建立一個defaultdict:

words = ['apple','bat','bar','atom','book']  
from collections import defaultdict  
by_letter = defaultdict(list)  
for word in words:  
    by_letter[word[0]].append(word)  
print by_letter   
#defaultdict(<type 'list'>, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})  
計數使用collections 庫的 Counter
>>> from collections import Counter
>>> c = Counter('hello world!')
>>> c
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1})
>>> c.most_common(1)
[('l', 3)]
>>> c.most_common(3)
[('l', 3), ('o', 2), ('h', 1)]
>>>

>>> import collections
>>> Card = collections.namedtuple('Card',['rank','suit'])
>>> class French_Deck(object):
...     rank = [ str(i) for i in range(2,11,1)] + list('JQKA')
...     suit = 'Spade,Club,Heart,Diamond'.split(',')
...     def __init__(self):
...         self._cards = [Card(r,s) for s in suit for r in rank]
...     def __getitem__(self,position):
...         return self._cards[position]
...     def __len__(self):
...         return len(self._cards)
...
>>> cards = French_Deck()
>>> len(cards)
56



from collections import namedtuple
stock_list = [['AAPL','10.30','11.90'],['YAHO','9.23','8.19'],['SINA','22.80','25.80']]
stock_info = namedtuple('stock_info',['name','start','end'])
[stock_info(name,start,end) for name,start,end in stock_list ]
stock_list



# 與 update 不同哦。。。

from collections import ChainMap

dict_1 = {'name':'Frank','age':18}
dict_2 = {'name':'','age':20}
dict_coalesce = ChainMap(dict_1,dict_2)
dict_coalesce['name']

itertools 模塊

from itertools import count, cycle, repeat, takewhile , chain, groupby

for i in count(1):
    if i<=10:
        print(i,end=',')
    else:
        break

print('\n'+'*'*100+'\n')

nums = takewhile(lambda n:n<=10,count(1))
print(list(nums))

for nl in repeat('\n',3):
    print(nl)

c = 0
for ch in cycle('ABC'):
    if c>=10:
        break
    else:
        print(ch,end=',')
    c+=1

print('\n'+'*'*100+'\n')
    
for ch in chain('ABC','XYZ'):
    print(ch)
    
for key,group in groupby('AAAaaabbBBBBBBBCCCccccddddEEEEDDD',lambda ch:ch.upper()):
    print(key,'--> ',list(group))
    
# -*- coding: utf-8 -*-
import itertools
from functools import reduce
def pi(N):
    ' 計算pi的值 '
    # step 1: 建立一個奇數序列: 1, 3, 5, 7, 9, ...
    odd_iter = itertools.count(1,2)
    
    # step 2: 取該序列的前N項: 1, 3, 5, 7, 9, ..., 2*N-1.
    odd_head = itertools.takewhile(lambda n:n<=2*N-1,odd_iter)
#     print(list(odd_head),end=',')
    # step 3: 添加正負符號並用4除: 4/1, -4/3, 4/5, -4/7, 4/9, ...
    odd_final = [4/n * ((-1)**i) for i,n in enumerate(odd_head)]
    # step 4: 求和:
    value = reduce(lambda x,y:x+y,odd_final)
    return value
# 測試:
print(pi(10))
print(pi(100))
print(pi(1000))
print(pi(10000))
assert 3.04 < pi(10) < 3.05
assert 3.13 < pi(100) < 3.14
assert 3.140 < pi(1000) < 3.141
assert 3.1414 < pi(10000) < 3.1415
print('ok')

contextlib 模塊

from contextlib import contextmanager,closing

xml.parsers.expat , lxml 等 模塊

import lxml
from xml.parsers.expat import ParserCreate

class DefaultSaxHandler(object):
    def start_element(self, name, attrs):
        print('sax:start_element: %s, attrs: %s' % (name, str(attrs)))

    def end_element(self, name):
        print('sax:end_element: %s' % name)

    def char_data(self, text):
        print('sax:char_data: %s' % text)

xml = r'''<?xml version="1.0"?>
<ol>
    <li><a href="/python">Python</a></li>
    <li><a href="/ruby">Ruby</a></li>
</ol>
'''

handler = DefaultSaxHandler()
parser = ParserCreate()
parser.StartElementHandler = handler.start_element
parser.EndElementHandler = handler.end_element
parser.CharacterDataHandler = handler.char_data
parser.Parse(xml)

html 解析模塊 html

from html.parser import HTMLParser
from html.entities import name2codepoint

class MyHTMLParser(HTMLParser):

    def handle_starttag(self, tag, attrs):
        print('<%s>' % tag)

    def handle_endtag(self, tag):
        print('</%s>' % tag)

    def handle_startendtag(self, tag, attrs):
        print('<%s/>' % tag)

    def handle_data(self, data):
        print(data)

    def handle_comment(self, data):
        print('<!--', data, '-->')

    def handle_entityref(self, name):
        print('&%s;' % name)

    def handle_charref(self, name):
        print('&#%s;' % name)

parser = MyHTMLParser()
parser.feed('''<html>
<head></head>
<body>
<!-- test html parser -->
    <p>Some <a href=\"#\">html</a> HTML&nbsp;tutorial...<br>END</p>
</body></html>''')

第三方 字符編碼檢測模塊 chardet

import chardet
data = '最新の主要ニュース'.encode('euc-jp')
chardet.detect(data)
{'confidence': 0.99, 'encoding': 'EUC-JP', 'language': 'Japanese'}

其餘第三方模塊

青出於藍的 requests >> urllib
Pillow(新)  PIL(2.7 遠古時代)
psutils  <== process and system utilities
將字典的值轉成object 的屬性,遞歸
d = {'a': 1, 'b': {'c': 2}, 'd': ["hi", {'foo': "bar"}]}

def my_dict2obj(args):
    class obj(object):
        def __init__(self,d):
            for key,value in d.items():
                if not isinstance(value,(list,tuple)):
                    setattr(self,key,obj(value) if isinstance(value,dict) else value)
                else:
                    setattr(self,key,[obj(i) if isinstance(i,dict) else i for i in value])
    return obj(args)

x = my_dict2obj(d)

print(x.d)


擴展拆箱
>>> a = [1,2,3,4,5,6]
>>> b,*c,d,e = a
>>> b
1
>>> c
[2, 3, 4]
>>> d
5
>>> e
6

給單詞按首字母分組
方法一:
words = ['apple','bat','bar','atom','book'] 
by_letter_grp_dict = {}
for word in words:
    letter = word[0]
    if letter in by_letter_grp_dict:
        by_letter_grp_dict[letter].append(word)
    else:
        by_letter_grp_dict[letter] = [word]
print(by_letter_grp_dict)
方法二:
內置的collections模塊有一個叫作defaultdict的類,它可使該過程更簡單。傳入一個類型或函數(用於生成字典各插槽所使用的默認值)便可建立一個defaultdict:

words = ['apple','bat','bar','atom','book']  
from collections import defaultdict  
by_letter = defaultdict(list)  
for word in words:  
    by_letter[word[0]].append(word)  
print by_letter   
#defaultdict(<type 'list'>, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})  
計數使用collections 庫的 Counter
>>> from collections import Counter
>>> c = Counter('hello world!')
>>> c
Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1, '!': 1})
>>> c.most_common(1)
[('l', 3)]
>>> c.most_common(3)
[('l', 3), ('o', 2), ('h', 1)]
>>>

我見青山多巍峨,料青山見我應如是

# -*- coding: utf-8 -*-
__author__ = 'Frank Li'
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1',6666))
clients = set()
print('server bind 127.0.0.1:6666...')

while 1:
    try:
        data,addr = server.recvfrom(1024)
        clients.add(addr)
        if not data or data.decode('utf-8')=='pong':
            continue
        print('%s:%s >>> %s' % (addr[0],addr[1],data.decode('utf-8')))
        for usr in clients:
            if usr!=addr:
                server.sendto(('%s:%s >>> %s' % (addr[0],addr[1],data.decode('utf-8'))).encode('utf-8'),usr)
    except Exception as e:
        pass
# -*- coding: utf-8 -*-
__author__ = 'Frank Li'

import socket,threading,os

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto(b'pong',('127.0.0.1',6666))

def myinput():
    while 1:
        try:
            msg = input('>>>')
            yield msg
        except Exception as e:
            os._exit(0)

def getMsg(client):
    while 1:
        try:
            r = client.recv(1024)
            print('\n',r.decode('utf-8'),'\n>>>',end='')
        except Exception as e:
            pass

c = myinput()
def sendMsg(msg):
    while 1:
        msg = next(c)
        client.sendto(msg.encode('utf-8'),('127.0.0.1',6666))

threading.Thread(target=sendMsg,args=(client,)).start()
threading.Thread(target=getMsg,args=(client,)).start()

inspect

import inspect

def a(a, b=0, *c, d, e=1, **f):
    pass

aa = inspect.signature(a)
print("inspect.signature(fn)是:%s" % aa)
print("inspect.signature(fn)的類型:%s" % (type(aa)))
print("\n")

bb = aa.parameters
print("signature.paramerters屬性是:%s" % bb)
print("ignature.paramerters屬性的類型是%s" % type(bb))
print("\n")

for cc, dd in bb.items():
    print("mappingproxy.items()返回的兩個值分別是:%s和%s" % (cc, dd))
    print("mappingproxy.items()返回的兩個值的類型分別是:%s和%s" % (type(cc), type(dd)))
    print("\n")
    ee = dd.kind
    print("Parameter.kind屬性是:%s" % ee)
    print("Parameter.kind屬性的類型是:%s" % type(ee))
    print("\n")
    gg = dd.default
    print("Parameter.default的值是: %s" % gg)
    print("Parameter.default的屬性是: %s" % type(gg))
    print("\n")


ff = inspect.Parameter.KEYWORD_ONLY
print("inspect.Parameter.KEYWORD_ONLY的值是:%s" % ff)
print("inspect.Parameter.KEYWORD_ONLY的類型是:%s" % type(ff))
import inspect


def func_a(arg_a, *args, arg_b='hello', **kwargs):
    print(arg_a, arg_b, args, kwargs)


if __name__ == '__main__':

    # 獲取函數簽名
    func_signature = inspect.signature(func_a)
    func_args = []
    # 獲取函數全部參數
    for k, v in func_signature.parameters.items():
        # 獲取函數參數後,須要判斷參數類型
        # 當kind爲 POSITIONAL_OR_KEYWORD,說明在這個參數以前沒有任何相似*args的參數,那這個函數能夠經過參數位置或者參數關鍵字進行調用
        # 這兩種參數要另外作判斷
        if str(v.kind) in ('POSITIONAL_OR_KEYWORD', 'KEYWORD_ONLY'):
            # 經過v.default能夠獲取到參數的默認值
            # 若是參數沒有默認值,則default的值爲:class inspect_empty
            # 因此經過v.default的__name__ 來判斷是否是_empty 若是是_empty表明沒有默認值
            # 同時,由於類自己是type類的實例,因此使用isinstance判斷是否是type類的實例
            if isinstance(v.default, type) and v.default.__name__ == '_empty':
                func_args.append({k: None})
            else:
                func_args.append({k: v.default})
        # 當kind爲 VAR_POSITIONAL時,說明參數是相似*args
        elif str(v.kind) == 'VAR_POSITIONAL':
            args_list = []
            func_args.append(args_list)
        # 當kind爲 VAR_KEYWORD時,說明參數是相似**kwargs
        elif str(v.kind) == 'VAR_KEYWORD':
            args_dict = {}
            func_args.append(args_dict)

    print(func_args)

相關文章
相關標籤/搜索