欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python3標(biāo)準(zhǔn)庫(kù)之functools管理函數(shù)的工具詳解

 更新時(shí)間:2020年02月27日 09:34:18   作者:@小灰灰  
functools模塊提供的主要工具就是partial類,可以用來(lái)“包裝”一個(gè)有默認(rèn)參數(shù)的callable對(duì)象。這篇文章主要介紹了Python3標(biāo)準(zhǔn)庫(kù)functools管理函數(shù)的工具的實(shí)例詳解,需要的朋友可以參考下

1. functools管理函數(shù)的工具

functools模塊提供了一些工具來(lái)調(diào)整或擴(kuò)展函數(shù)和其他callable對(duì)象,從而不必完全重寫(xiě)。

1.1 修飾符

functools模塊提供的主要工具就是partial類,可以用來(lái)“包裝”一個(gè)有默認(rèn)參數(shù)的callable對(duì)象。得到的對(duì)象本身就是callable,可以把它看作是原來(lái)的函數(shù)。它與原函數(shù)的參數(shù)完全相同,調(diào)用時(shí)還可以提供額外的位置或命名函數(shù)??梢允褂胮artial而不是lambda為函數(shù)提供默認(rèn)參數(shù),有些參數(shù)可以不指定。

1.1.1 部分對(duì)象

第一個(gè)例子顯示了函數(shù)myfunc()的兩個(gè)簡(jiǎn)單partial對(duì)象。show_details()的輸出中包含這個(gè)部分對(duì)象(partial object)的func、args和keywords屬性。

import functools
def myfunc(a, b=2):
 "Docstring for myfunc()."
 print(' called myfunc with:', (a, b))
def show_details(name, f, is_partial=False):
 "Show details of a callable object."
 print('{}:'.format(name))
 print(' object:', f)
 if not is_partial:
  print(' __name__:', f.__name__)
 if is_partial:
  print(' func:', f.func)
  print(' args:', f.args)
  print(' keywords:', f.keywords)
 return
show_details('myfunc', myfunc)
myfunc('a', 3)
print()
# Set a different default value for 'b', but require
# the caller to provide 'a'.
p1 = functools.partial(myfunc, b=4)
show_details('partial with named default', p1, True)
p1('passing a')
p1('override b', b=5)
print()
# Set default values for both 'a' and 'b'.
p2 = functools.partial(myfunc, 'default a', b=99)
show_details('partial with defaults', p2, True)
p2()
p2(b='override b')
print()
print('Insufficient arguments:')
p1()

在這個(gè)例子的最后,調(diào)用了之前創(chuàng)建的第一個(gè)partial,但沒(méi)有為a傳入一個(gè)值,這便會(huì)導(dǎo)致一個(gè)異常。

1.1.2 獲取函數(shù)屬性

默認(rèn)的,partial對(duì)象沒(méi)有__name__或__doc__屬性。如果沒(méi)有這些屬性,被修飾的函數(shù)將更難調(diào)試。使用update_wrapper()可以從原函數(shù)將屬性復(fù)制或增加到partial對(duì)象。

import functools
def myfunc(a, b=2):
 "Docstring for myfunc()."
 print(' called myfunc with:', (a, b))
def show_details(name, f):
 "Show details of a callable object."
 print('{}:'.format(name))
 print(' object:', f)
 print(' __name__:', end=' ')
 try:
  print(f.__name__)
 except AttributeError:
  print('(no __name__)')
 print(' __doc__', repr(f.__doc__))
 print()
show_details('myfunc', myfunc)
p1 = functools.partial(myfunc, b=4)
show_details('raw wrapper', p1)
print('Updating wrapper:')
print(' assign:', functools.WRAPPER_ASSIGNMENTS)
print(' update:', functools.WRAPPER_UPDATES)
print()
functools.update_wrapper(p1, myfunc)
show_details('updated wrapper', p1)

增加到包裝器的屬性在WRAPPER_ASSIGNMENTS中定義,另外WARPPER_UPDATES列出了要修改的值。

1.1.3 其他callable

partial適用于任何callable對(duì)象,而不只是獨(dú)立的函數(shù)。

import functools
class MyClass:
 "Demonstration class for functools"
 
 def __call__(self, e, f=6):
  "Docstring for MyClass.__call__"
  print(' called object with:', (self, e, f))
def show_details(name, f):
 "Show details of a callable object."
 print('{}:'.format(name))
 print(' object:', f)
 print(' __name__:', end=' ')
 try:
  print(f.__name__)
 except AttributeError:
  print('(no __name__)')
 print(' __doc__', repr(f.__doc__))
 return
o = MyClass()
show_details('instance', o)
o('e goes here')
print()
p = functools.partial(o, e='default for e', f=8)
functools.update_wrapper(p, o)
show_details('instance wrapper', p)
p()

這個(gè)例子從一個(gè)包含__call__()方法的類實(shí)例中創(chuàng)建部分對(duì)象。

1.1.4 方法和函數(shù)

partial()返回一個(gè)可以直接使用的callable,partialmethod()返回的callable則可以用作對(duì)象的非綁定方法。在下面的例子中,這個(gè)獨(dú)立函數(shù)兩次被增加為MyClass的屬性,一次使用partialmethod()作為method1(),另一次使用partial()作為method2()。

import functools
def standalone(self, a=1, b=2):
 "Standalone function"
 print(' called standalone with:', (self, a, b))
 if self is not None:
  print(' self.attr =', self.attr)
class MyClass:
 "Demonstration class for functools"
 
 def __init__(self):
  self.attr = 'instance attribute'
 method1 = functools.partialmethod(standalone)
 method2 = functools.partial(standalone)
o = MyClass()
print('standalone')
standalone(None)
print()
print('method1 as partialmethod')
o.method1()
print()
print('method2 as partial')
try:
 o.method2()
except TypeError as err:
 print('ERROR: {}'.format(err))

method1()可以從MyClass的一個(gè)實(shí)例中調(diào)用,這個(gè)實(shí)例作為第一個(gè)參數(shù)傳入,這與采用通常方法定義的方法是一樣的。method2()未被定義為綁定方法,所以必須顯式傳遞self參數(shù);否則,這個(gè)調(diào)用會(huì)導(dǎo)致TypeError。

1.1.5 獲取修飾符的函數(shù)屬性

更新所包裝callable的屬性對(duì)修飾符尤其有用,因?yàn)檗D(zhuǎn)換后的函數(shù)最后會(huì)得到原“裸”函數(shù)的屬性。

import functools
def show_details(name, f):
 "Show details of a callable object."
 print('{}:'.format(name))
 print(' object:', f)
 print(' __name__:', end=' ')
 try:
  print(f.__name__)
 except AttributeError:
  print('(no __name__)')
 print(' __doc__', repr(f.__doc__))
 print()
def simple_decorator(f):
 @functools.wraps(f)
 def decorated(a='decorated defaults', b=1):
  print(' decorated:', (a, b))
  print(' ', end=' ')
  return f(a, b=b)
 return decorated
def myfunc(a, b=2):
 "myfunc() is not complicated"
 print(' myfunc:', (a, b))
 return
 
# The raw function
show_details('myfunc', myfunc)
myfunc('unwrapped, default b')
myfunc('unwrapped, passing b', 3)
print()
# Wrap explicitly
wrapped_myfunc = simple_decorator(myfunc)
show_details('wrapped_myfunc', wrapped_myfunc)
wrapped_myfunc()
wrapped_myfunc('args to wrapped', 4)
print()
# Wrap with decorator syntax
@simple_decorator
def decorated_myfunc(a, b):
 myfunc(a, b)
 return
show_details('decorated_myfunc', decorated_myfunc)
decorated_myfunc()
decorated_myfunc('args to decorated', 4)

functools提供了一個(gè)修飾符wraps(),它會(huì)對(duì)所修飾的函數(shù)應(yīng)用update_wrapper()。

1.2 比較

在Python 2中,類可以定義一個(gè)__cmp__()方法,它會(huì)根據(jù)這個(gè)對(duì)象小于、對(duì)于或者大于所比較的元素而分別返回-1、0或1.Python 2.1引入了富比較(rich comparison)方法API(__lt__()、__le__()、__eq__()、__ne__()、__gt__()和__ge__()) ,可以完成一個(gè)比較操作并返回一個(gè)布爾值。Python 3廢棄了__cmp__()而代之以這些新的方法,另外functools提供了一些工具,從而能更容易地編寫(xiě)符合新要求的類,即符合Python 3中新的比較需求。

1.2.1 富比較

設(shè)計(jì)富比較API是為了支持涉及復(fù)雜比較的類,以最高效的方式實(shí)現(xiàn)各個(gè)測(cè)試。不過(guò),如果比較相對(duì)簡(jiǎn)單的類,就沒(méi)有必要手動(dòng)地創(chuàng)建各個(gè)富比價(jià)方法了。total_ordering()類修飾符可以為一個(gè)提供了部分方法的類增加其余的方法。

import functools
import inspect
from pprint import pprint
@functools.total_ordering
class MyObject:
 def __init__(self, val):
  self.val = val
 def __eq__(self, other):
  print(' testing __eq__({}, {})'.format(
   self.val, other.val))
  return self.val == other.val
 def __gt__(self, other):
  print(' testing __gt__({}, {})'.format(
   self.val, other.val))
  return self.val > other.val
print('Methods:\n')
pprint(inspect.getmembers(MyObject, inspect.isfunction))
a = MyObject(1)
b = MyObject(2)
print('\nComparisons:')
for expr in ['a < b', 'a <= b', 'a == b', 'a >= b', 'a > b']:
 print('\n{:<6}:'.format(expr))
 result = eval(expr)
 print(' result of {}: {}'.format(expr, result))

這個(gè)類必須提供__eq__()和另外一個(gè)富比較方法的實(shí)現(xiàn)。這個(gè)修飾符會(huì)增加其余方法的實(shí)現(xiàn),它們會(huì)使用所提供的比較。如果無(wú)法完成一個(gè)比較,這個(gè)方法應(yīng)當(dāng)返回NotImplemented,從而在另一個(gè)對(duì)象上使用逆比較操作符嘗試比較,如果仍無(wú)法比較,便會(huì)完全失敗。

1.2.2 比對(duì)序

由于Python 3廢棄了老式的比較函數(shù),sort()之類的函數(shù)中也不再支持cmp參數(shù)。對(duì)于使用了比較函數(shù)的較老的程序,可以用cmp_to_key()將比較函數(shù)轉(zhuǎn)換為一個(gè)返回比較鍵(collation key)的函數(shù),這個(gè)鍵用于確定元素在最終序列中的位置。

import functools
class MyObject:
 def __init__(self, val):
  self.val = val
 def __str__(self):
  return 'MyObject({})'.format(self.val)
def compare_obj(a, b):
 """Old-style comparison function.
 """
 print('comparing {} and {}'.format(a, b))
 if a.val < b.val:
  return -1
 elif a.val > b.val:
  return 1
 return 0
# Make a key function using cmp_to_key()
get_key = functools.cmp_to_key(compare_obj)
def get_key_wrapper(o):
 "Wrapper function for get_key to allow for print statements."
 new_key = get_key(o)
 print('key_wrapper({}) -> {!r}'.format(o, new_key))
 return new_key
objs = [MyObject(x) for x in range(5, 0, -1)]
for o in sorted(objs, key=get_key_wrapper):
 print(o)

正常情況下,可以直接使用cmp_to_key(),不過(guò)這個(gè)例子中引入了一個(gè)額外的包裝器函數(shù),這樣調(diào)用鍵函數(shù)時(shí)可以打印更多的信息。

如輸出所示,sorted()首先對(duì)序列中的每一個(gè)元素調(diào)用get_key_wrapper()以生成一個(gè)鍵。cmp_to_key()返回的鍵是functools中定義的一個(gè)類的實(shí)例,這個(gè)類使用傳入的老式比較函數(shù)實(shí)現(xiàn)富比較API。所有鍵都創(chuàng)建之后,通過(guò)比較這些鍵來(lái)對(duì)序列排序。

1.3 緩存

lru_cache()修飾符將一個(gè)函數(shù)包裝在一個(gè)“最近最少使用的”緩存中。函數(shù)的參數(shù)用來(lái)建立一個(gè)散列鍵,然后映射到結(jié)果。后續(xù)的調(diào)用如果有相同的參數(shù),就會(huì)從這個(gè)緩存獲取值而不會(huì)再次調(diào)用函數(shù)。這個(gè)修飾符還會(huì)為函數(shù)增加方法來(lái)檢查緩存的狀態(tài)(cache_info())和清空緩存(cache_clear())。

import functools
@functools.lru_cache()
def expensive(a, b):
 print('expensive({}, {})'.format(a, b))
 return a * b
MAX = 2
 
print('First set of calls:')
for i in range(MAX):
 for j in range(MAX):
  expensive(i, j)
print(expensive.cache_info())
print('\nSecond set of calls:')
for i in range(MAX + 1):
 for j in range(MAX + 1):
  expensive(i, j)
print(expensive.cache_info())
print('\nClearing cache:')
expensive.cache_clear()
print(expensive.cache_info())
print('\nThird set of calls:')
for i in range(MAX):
 for j in range(MAX):
  expensive(i, j)
print(expensive.cache_info())

這個(gè)例子在一組嵌套循環(huán)中執(zhí)行了多個(gè)expensive()調(diào)用。第二次調(diào)用時(shí)有相同的參數(shù)值,結(jié)果在緩存中。清空緩存并再次運(yùn)行循環(huán)時(shí),這些值必須重新計(jì)算。

為了避免一個(gè)長(zhǎng)時(shí)間運(yùn)行的進(jìn)程導(dǎo)致緩存無(wú)限制的擴(kuò)張,要指定一個(gè)最大大小。默認(rèn)為128個(gè)元素,不過(guò)對(duì)于每個(gè)緩存可以用maxsize參數(shù)改變這個(gè)大小。

import functools
@functools.lru_cache(maxsize=2)
def expensive(a, b):
 print('called expensive({}, {})'.format(a, b))
 return a * b
def make_call(a, b):
 print('({}, {})'.format(a, b), end=' ')
 pre_hits = expensive.cache_info().hits
 expensive(a, b)
 post_hits = expensive.cache_info().hits
 if post_hits > pre_hits:
  print('cache hit')
print('Establish the cache')
make_call(1, 2)
make_call(2, 3)
print('\nUse cached items')
make_call(1, 2)
make_call(2, 3)
print('\nCompute a new value, triggering cache expiration')
make_call(3, 4)
print('\nCache still contains one old item')
make_call(2, 3)
print('\nOldest item needs to be recomputed')
make_call(1, 2)

在這個(gè)例子中,緩存大小設(shè)置為2個(gè)元素。使用第3組不同的參數(shù)(3,4)時(shí),緩存中最老的元素會(huì)被清除,代之以這個(gè)新結(jié)果。

lru_cache()管理的緩存中鍵必須是可散列的,所以對(duì)于用緩存查找包裝的函數(shù),它的所有參數(shù)都必須是可散列的。

import functools
@functools.lru_cache(maxsize=2)
def expensive(a, b):
 print('called expensive({}, {})'.format(a, b))
 return a * b
def make_call(a, b):
 print('({}, {})'.format(a, b), end=' ')
 pre_hits = expensive.cache_info().hits
 expensive(a, b)
 post_hits = expensive.cache_info().hits
 if post_hits > pre_hits:
  print('cache hit')
make_call(1, 2)
try:
 make_call([1], 2)
except TypeError as err:
 print('ERROR: {}'.format(err))
try:
 make_call(1, {'2': 'two'})
except TypeError as err:
 print('ERROR: {}'.format(err))

如果將一個(gè)不能散列的對(duì)象傳入這個(gè)函數(shù),則會(huì)產(chǎn)生一個(gè)TypeError。

1.4 縮減數(shù)據(jù)集

reduce()函數(shù)取一個(gè)callable和一個(gè)數(shù)據(jù)序列作為輸入。它會(huì)用這個(gè)序列中的值調(diào)用這個(gè)callable,并累加得到的輸出來(lái)生成單個(gè)值作為輸出。

import functools
def do_reduce(a, b):
 print('do_reduce({}, {})'.format(a, b))
 return a + b
data = range(1, 5)
print(data)
result = functools.reduce(do_reduce, data)
print('result: {}'.format(result))

這個(gè)例子會(huì)累加序列中的數(shù)。

可選的initializer參數(shù)放在序列最前面,像其他元素一樣處理。可以利用這個(gè)參數(shù)以新輸入更新前面計(jì)算的值。

import functools
def do_reduce(a, b):
 print('do_reduce({}, {})'.format(a, b))
 return a + b
data = range(1, 5)
print(data)
result = functools.reduce(do_reduce, data, 99)
print('result: {}'.format(result))

在這個(gè)例子中,使用前面的總和99來(lái)初始化reduce()計(jì)算的值。

如果沒(méi)有initializer參數(shù),那么只有一個(gè)元素的序列會(huì)自動(dòng)縮減為這個(gè)值??樟斜頃?huì)生成一個(gè)錯(cuò)誤,除非提供一個(gè)initializer參數(shù)。

import functools
def do_reduce(a, b):
 print('do_reduce({}, {})'.format(a, b))
 return a + b
print('Single item in sequence:',
  functools.reduce(do_reduce, [1]))
print('Single item in sequence with initializer:',
  functools.reduce(do_reduce, [1], 99))
print('Empty sequence with initializer:',
  functools.reduce(do_reduce, [], 99))
try:
 print('Empty sequence:', functools.reduce(do_reduce, []))
except TypeError as err:
 print('ERROR: {}'.format(err))

由于initializer參數(shù)相當(dāng)于一個(gè)默認(rèn)值,但也要與新值結(jié)合(如果輸入序列不為空),所以必須仔細(xì)考慮這個(gè)參數(shù)的使用是否適當(dāng),這很重要。如果默認(rèn)值與新值結(jié)合沒(méi)有意義,那么最好是捕獲TypeError而不是傳入一個(gè)initializer參數(shù)。

1.5 泛型函數(shù)

在類似Python的動(dòng)態(tài)類型語(yǔ)言中,通常需要基于參數(shù)的類型完成稍有不同的操作,特別是在處理元素列表與單個(gè)元素的差別時(shí)。直接檢查參數(shù)的類型固然很簡(jiǎn)單,但是有些情況下,行為差異可能被隔離到單個(gè)的函數(shù)中,對(duì)于這些情況,functools提供了singledispatch()修飾符來(lái)注冊(cè)一組泛型函數(shù)(generic function),可以根據(jù)函數(shù)第一個(gè)參數(shù)類型自動(dòng)切換。

import functools
@functools.singledispatch
def myfunc(arg):
 print('default myfunc({!r})'.format(arg))
@myfunc.register(int)
def myfunc_int(arg):
 print('myfunc_int({})'.format(arg))
@myfunc.register(list)
def myfunc_list(arg):
 print('myfunc_list()')
 for item in arg:
  print(' {}'.format(item))
myfunc('string argument')
myfunc(1)
myfunc(2.3)
myfunc(['a', 'b', 'c'])

新函數(shù)的register()屬性相當(dāng)于另一個(gè)修飾符,用于注冊(cè)替代實(shí)現(xiàn)。用singledispatch()包裝的第一個(gè)函數(shù)是默認(rèn)實(shí)現(xiàn),在未指定其他類型特定函數(shù)時(shí)就使用這個(gè)默認(rèn)實(shí)現(xiàn),在這個(gè)例子中特定類型就是float。

沒(méi)有找到這個(gè)類型的完全匹配時(shí),會(huì)計(jì)算繼承順序,并使用最接近的匹配類型。

import functools
class A:
 pass
class B(A):
 pass
class C(A):
 pass
class D(B):
 pass
class E(C, D):
 pass
@functools.singledispatch
def myfunc(arg):
 print('default myfunc({})'.format(arg.__class__.__name__))
@myfunc.register(A)
def myfunc_A(arg):
 print('myfunc_A({})'.format(arg.__class__.__name__))
@myfunc.register(B)
def myfunc_B(arg):
 print('myfunc_B({})'.format(arg.__class__.__name__))
@myfunc.register(C)
def myfunc_C(arg):
 print('myfunc_C({})'.format(arg.__class__.__name__))
myfunc(A())
myfunc(B())
myfunc(C())
myfunc(D())
myfunc(E())

在這個(gè)例子中,類D和E與已注冊(cè)的任何泛型函數(shù)都不完全匹配,所選擇的函數(shù)取決于類層次結(jié)構(gòu)。

總結(jié)

到此這篇關(guān)于Python3標(biāo)準(zhǔn)庫(kù)之functools管理函數(shù)的工具詳解的文章就介紹到這了,更多相關(guān)Python3 functools管理函數(shù)工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python性能測(cè)試工具locust的使用

    python性能測(cè)試工具locust的使用

    這篇文章主要介紹了python性能測(cè)試工具locust的使用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-12-12
  • Python騷操作完美實(shí)現(xiàn)短視頻偽原創(chuàng)

    Python騷操作完美實(shí)現(xiàn)短視頻偽原創(chuàng)

    剪輯的視頻上傳到某平臺(tái)碰到降權(quán)怎么辦?視頻平臺(tái)都有一套自己的鑒別算法,專門(mén)用于處理視頻的二次剪輯,本篇我們來(lái)用python做一些特殊處理
    2022-02-02
  • python 獲取sqlite3數(shù)據(jù)庫(kù)的表名和表字段名的實(shí)例

    python 獲取sqlite3數(shù)據(jù)庫(kù)的表名和表字段名的實(shí)例

    今天小編就為大家分享一篇python 獲取sqlite3數(shù)據(jù)庫(kù)的表名和表字段名的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Series和DataFrame使用簡(jiǎn)單入門(mén)

    Series和DataFrame使用簡(jiǎn)單入門(mén)

    這篇文章主要介紹了Series和DataFrame使用簡(jiǎn)單入門(mén),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • python 繪制擬合曲線并加指定點(diǎn)標(biāo)識(shí)的實(shí)現(xiàn)

    python 繪制擬合曲線并加指定點(diǎn)標(biāo)識(shí)的實(shí)現(xiàn)

    這篇文章主要介紹了python 繪制擬合曲線并加指定點(diǎn)標(biāo)識(shí)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 詳解python logging日志傳輸

    詳解python logging日志傳輸

    這篇文章主要介紹了python logging日志傳輸?shù)南嚓P(guān)資料,文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Python交換字典鍵值對(duì)的四種方法實(shí)例

    Python交換字典鍵值對(duì)的四種方法實(shí)例

    字典中有成對(duì)出現(xiàn)的鍵和值,但是字典中的鍵值對(duì)不是都能修改的,只有值才能修改,下面這篇文章主要給大家介紹了關(guān)于Python交換字典鍵值對(duì)的四種方法,需要的朋友可以參考下
    2022-12-12
  • 詳解python單例模式與metaclass

    詳解python單例模式與metaclass

    這篇文章主要介紹了python單例模式與metaclass,文章介紹了單例模式的實(shí)現(xiàn)方式
    2016-01-01
  • Python對(duì)130w+張圖片檢索的實(shí)現(xiàn)方法

    Python對(duì)130w+張圖片檢索的實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Python對(duì)130w+張圖片檢索的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • python生成隨機(jī)mac地址的方法

    python生成隨機(jī)mac地址的方法

    這篇文章主要介紹了python生成隨機(jī)mac地址的方法,涉及Python操作隨機(jī)字符串的技巧,需要的朋友可以參考下
    2015-03-03

最新評(píng)論