2009-04-18 103 views
18

我對一些Python套接字代碼的工作目前正使用的socket.fromfd()功能是可用的。確定一個功能的Python模塊

然而,這種方法並不適用於所有的平臺,所以我寫的,該方法沒有定義的情況下,一些備用的代碼。

什麼是確定的方法是在運行時定義的最佳方法是什麼?下面是否足夠或有更好的習語?

if 'fromfd' in dir(socket): 
    sock = socket.fromfd(...) 
else: 
    sock = socket.socket(...) 

我稍微關注的是,dir()文件似乎不鼓勵使用。 getattr()是更好的選擇,如:

if getattr(socket, 'fromfd', None) is not None: 
    sock = socket.fromfd(...) 
else: 
    sock = socket.socket(...) 

想法?

編輯由於Paolo指出,這個問題是nearly a duplicate關於確定屬性的存在問題。然而,由於所使用的術語是不相交(LK的「對象有一個屬性」 VS我「模塊有一個功能」)它可能有助於保持這一問題的可搜索性,除非兩個可以結合起來。

回答

24

hasattr()是最好的選擇。去那。 :)

if hasattr(socket, 'fromfd'): 
    pass 
else: 
    pass 

編輯:其實,根據文檔的所有hasattr正在做的是調用GETATTR和捕捉異常。所以如果你想砍掉中間人,你應該選擇馬克格的答案。

編輯:我也剛剛意識到這個問題實際上是一個duplicate。其中一個答案討論了你擁有的兩個選項的優點:捕捉異常(「容易請求寬恕而不是許可」)或者簡單地先檢查(「先看你跳躍」)。老實說,我更多的是後者,但似乎Python社區傾向於以前的學派。

+0

我沒有看到這個答案如何值得downvote ...:/ – 2009-04-18 19:42:10

+1

我寧願hasattr超過GETATTR只是可讀性的緣故! – bobince 2009-04-19 02:25:18

19

或者乾脆使用try..except塊:

try: 
    sock = socket.fromfd(...) 
except AttributeError: 
    sock = socket.socket(...) 
3

hasattr(OBJ, '爲AttributeName')可能是一個更好的。 hasattr將嘗試訪問該屬性,如果不存在,它將返回false。

在python中可能有動態方法,即在您嘗試訪問它們時創建的方法。他們不會在dir(...)中。但是,hasattr會檢查它。

>>> class C(object): 
... def __init__(self): 
...  pass 
... def mymethod1(self): 
...  print "In #1" 
... def __getattr__(self, name): 
...  if name == 'mymethod2': 
...  def func(): 
...   print "In my super meta #2" 
...  return func 
...  else: 
...  raise AttributeError 
... 
>>> c = C() 
>>> 'mymethod1' in dir(c) 
True 
>>> hasattr(c, 'mymethod1') 
True 
>>> c.mymethod1() 
In #1 
>>> 'mymethod2' in dir(c) 
False 
>>> hasattr(c, 'mymethod2') 
True 
>>> c.mymethod2() 
In my super meta #2