1. 程式人生 > 其它 >python 基礎之常用函式eval(),filter(),extend()等

python 基礎之常用函式eval(),filter(),extend()等

技術標籤:python列表python

get, getattr, __getattribute__的區別

ref
obj.getattribute(self, name)
在例項訪問屬性的時候無條件被呼叫。如果class中定義了__getattr__(),getattr()也不會被呼叫,除非顯示的呼叫或者沒有訪問到屬性引發AttributeError異常

obj.getattr(self, name)
當一般位置找不到屬性時,會呼叫__getattr__()返回一個值,如果不存在__getattr__()方法則會引發AttributeError異常。

obj.get(self, instance, owner)

如果類定義了它,則這個類可以被稱為descriptor(描述符),owner是所有者的類,instance是訪問descriptor的例項,如果不是通過例項訪問,而是通過類訪問的畫,instance則為None。

descriptor的例項自己訪問自己是不會觸發__get__,而會觸發__call__,只有descriptor作為其它類的屬性才有意義。

類裡面是預設不會提供__get__()方法的

getattr(self, name), setattr(self, name, value),delattr(self, name)

ref
在舊式類中,可以使用__getattr__(self, name), setattr

(self, name, value)以及__delattr__(self, name), 分別適用於當特性name被訪問時且物件沒有相應的特性時被自動呼叫,當試圖給特性name賦值時會被自動呼叫以及當試圖刪除特性name時被自動呼叫。

class Rectangle:
	def __init__(self):
		self.width = 0
		self.height = 0
	def __setattr__(self, name, value):
		if name == 'size':
			self.width, self.height = value
		else:
			self.__dict__[
name] = value def __getattr__(self, name): if name == 'size': return self.width, self.height else: raise AttributeError def __delattr__(self, name): if name == 'size': del self.__dict__['width'] del self.__dict__['height'] else: if name in self.__dict__: del self.__dict__[name] else: raise KeyError

注意__dict__方法包含一個字典,字典裡是所有例項的屬性, getattr 只有在訪問不存在的成員時才會被呼叫。如果型別繼承自 object,可以使用__getattribute__ 來攔截所有(包括不存在的成員)的獲取操作, 其也可以攔截對__dict__的訪問,因此__getattribute__ 中不要使用 “return self.dict[name]” 來返回結果,因為在訪問 “self.dict” 時同樣會被 getattribute 攔截,從而造成無限遞迴形成死迴圈。

訪問__getattribute__中與self相關的特性,可以使用超類的__getattribute__(使用super函式)來獲取操作。

class A(object):
	def __getattribute__(self, name):
		return object.__getattribute__(self, name)

常用函式

eval()

ref
eval(expression[, globals[, locals]])用來執行一個字串表示式,並返回表示式的值。

x = 7
>>> eval( '3 * x' )
21
>>> eval('pow(2,2)')
4
>>> eval('2 + 2')
4
>>> n=81
>>> eval("n + 4")
85

可以把list,tuple,dict和string相互轉化。

a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
print b
#[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]

指定globals

a=10;
g={'a':4}
print(eval("a+1",g))
# eval中提供了globals引數,這時候eval的作用域就是g指定的這個字典了,也就是外面的a=10被遮蔽掉了,eval是看不見的,所以使用了a為4的值。

指定locals

a=10
b=20
c=30
g={'a':6,'b':8}
t={'b':100,'c':10}
print(eval('a+b+c',g,t))

要確保第一個引數expression滿足表示式的要求,它是可以被解析然後計算的

s="abck"
print(eval(s))## 輸出NameError: name 'abck' is not defined
#當eval剝去了"abck"的外面的引號的時候,它會對它進行解析,然後滿足要求後進行計算,然後它解析到的是abcd,請注意,程式報出的錯誤是NameError,也就是說,當它解析到這個表示式是不可以計算後,它就會查詢它是不是一個變數的名字,如果是一個變數的名字,那麼它會輸出這個變數的內容,否則就會產生這種報錯。
s="abck"
print(eval('s')) ## 輸出abck

s='"sas"'
print(eval(s))		## 輸出sas
#eval在執行的時候是隻會去除同種型別的引號的,對於單引號和雙引號它是加以區分的
s='["a","b","c"]'
print(eval(s))

a=10
b=20
c=30
s='[a,b,c]'
print(eval(s))		## [10, 20, 30]
# eval檢查到列表的‘[’‘]’符號時,是會對裡面的元素進行解析的,這裡a、b、c顯然不是具體的資料,便去查詢它們是否是變數名,然後確認是變數名後,用它們的內容替換掉它。

filter()

# filter(function, iterable)
def is_odd(n):
    return n % 2 == 1
 
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)			## [1, 3, 5, 7, 9]

import math
def is_sqr(x):
    return math.sqrt(x) % 1 == 0

newlist = list(filter(is_sqrt, range(1, 101)))				#注意這裡轉成list
print(newlist) 			## [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

extend()

該方法沒有返回值,但會在已存在的列表中新增新的列表內容。

list.extend(seq)
num = [1,2]
num.extend([1]*2)	## [1, 2, 1, 1]

append與extend區別:
append命令是將整個物件加在列表末尾;而extend命令是將新物件中的元素逐一加在列表的末尾。
append命令可以新增單個元素,也可以新增可迭代物件;而extend命令只能新增可迭代物件。

List=[]
list.extend([1,2,3])
print(list)			##[1,2,3]

List=[]
list.append([1,2,3])
print(list)			##[[1,2,3]]