2013-03-01 48 views
2

考慮你有兩個python文件,如下所述。假設一個是通用包(class2),另一個包含特定的覆蓋並作爲可執行文件(class1)。python命名空間:__main __。Class不是isinstance of package.Class

class1.py:

#!/usr/bin/python 
class Test(object): 
    pass 

class Verificator(): 
    def check(self, myObject): 
     if not isinstance(myObject, Test): 
      print "%s is no instance of %s" % (type(myObject),Test) 
     else: 
      print "OK!" 

if __name__ == '__main__': 
    from class2 import getTest 

    v = Verificator() 
    t = Test() 
    v.check(t) 
    s = getTest() 
    v.check(s) 

class2.py:

from class1 import Test 
def getTest(): 
    return Test() 

什麼情況是,首先檢查是確定的,其中第二失敗。原因是t__main__.Testsclass1.Testv.check()檢查__main__.Test,但在一天結束時它是同一班,對吧?

有沒有辦法寫v.check()這樣它也接受class1.Test對象或者其他任何方式來解決這個問題?

回答

-2

您可以使用type()功能(你會發現這個調用相當普遍,事實上!):

#!/usr/bin/python 
class Test(object): 
    pass 

class Verificator(): 
    def check(self, myObject): 
     if not isinstance(type(myObject), type(Test)): 
      print "%s is no instance of %s" % (type(myObject),Test) 
     else: 
      print "OK!" 

if __name__ == '__main__': 
    from class2 import getTest 

    v = Verificator() 
    t = Test() 
    v.check(t) 
    s = getTest() 
    v.check(s) 

的可能更糟的解決方案:

if not isinstance(myObject.__class__, Test.__class__): # Use __class__ here. 

他們當然當量,但它被認爲是不好的形式,需要使用雙下劃線成員,除非你非常需要!儘管如此,值得了解它們的存在,因此,爲什麼我將這一個包含在我的答案中。

請注意,據我所知,發生這種情況的原因是,當您運行python class1.py時,class1.py將沒有模塊。因此,python將所有內容都放到了__main__模塊中。這個不是當你從任何其他腳本導入它的情況下,所以看到作爲__main__模塊的一部分的東西實際上是特例!

+1

我會使用'type(myObject)'代替。它歸結爲同樣的事情,但使用官方的API,而不是直接進入hook屬性。 – 2013-03-01 14:36:52

+0

+1,我會編輯我的答案,使這一點更加突出。 – 2013-03-01 14:37:39

+4

檢查'isinstance(type(myObject),type(Test))'只測試'myObject'的類型是由'Test'的元類創建的。對於由默認元類創建的任何兩種新式類都是如此,幾乎可以肯定不是OP要求的。 – user4815162342 2013-03-01 14:46:45

3

如果您打算從其他地方進口class1.py,移動頂級代碼(if __name__ == '__main__': ...乾脆一個單獨的文件,這樣一來無論是主文件,並用相同的class1.Testclass2工作。

這樣做幾乎任何東西雖然你可以通過切換isinstancetype(myObject).__name__ == ...解決當前的問題,但事實仍然是,你的Python進程包含兩個只有一個類的Test類,否則難以區分的類彼此不知道,其他的issubclass測試。這實際上保證了難以診斷的錯誤。

編輯
另一種選擇是作爲主要執行的時候,在你的答案明確從class1導入類。建議更進一步,並確保這些類不是雙重定義的。例如,你可以用sys.exit(0)移動if __name__ == '__main__'塊到開頭的文件的,並結束它:

if __name__ == '__main__': 
    import class1, class2 
    ... use only the public API with module prefixes ... 
    sys.exit(0) 

# the rest of the module follows here 
+0

這可能是一個乾淨的解決方案,但我實際上希望避免將我的場景文件分爲兩部分。 – 2013-03-01 16:41:15

0

謝謝你的提示,並最終幫助我在正確的方向進行試驗。我剛剛在這個玩具模型中找到的解決方案是使用導入來修復命名空間問題。爲了排除user4815162342指出的問題,我在class1中添加了另一個類。下面的代碼爲class1.py似乎做,我想要的:

#!/usr/bin/python 
class Test(object): 
    pass 

class Toast(object): 
    pass 

class Verificator(): 
    def check(self, myObject): 
     if not isinstance(myObject, Test): 
      print "NOPE: %s is no instance of %s" % (type(myObject),Test) 
     else: 
      print "OK: %s is instance of %s" % (type(myObject),Test) 

if __name__ == '__main__': 
    from class2 import getTest 
    from class1 import Test, Toast 

    v = Verificator() 
    t = Test() 
    v.check(t) 
    t = getTest() 
    v.check(t) 
    t = Toast() 
    v.check(t)