2012-12-23 79 views
0

我有一大堆由Django項目/站點共享的Django應用程序庫。在每個項目/站點中,有一個選項可以定義一個混合進類內的混合類,這個混合類將被混合到一個庫內基類(許多模型的子類)中。Python裝飾器限制一個方法到一個特定的類?

對於這個例子,假設庫中的基類是PermalinkBase,混合類是ProjectPermalinkBaseMixIn

由於PermalinkBase的子類很多,因此ProjectPermalinkBaseMixIn中定義的所有方法/性質都不會被PermalinkBase的所有子類使用。

我想編寫一個裝飾器,可以應用於ProjectPermalinkBaseMixIn中的方法/屬性,以便限制它們從非批准的類訪問時運行(或至少返回None)。

下面是我現在做:

class ProjectPermalinkBaseMixIn(object): 
    """ 
    Project-specific Mix-In Class to `apps.base.models.PermalinkBase` 
    """ 

    def is_video_in_season(self, season): 
     # Ensure this only runs if it is being called from the video model 
     if self.__class__.__name__ != 'Video': 
      to_return = None 
     else: 
      videos_in_season = season.videos_in_this_season.all() 
      if self in list(videos_in_season): 
       to_return = True 
      else: 
       to_return False 

     return to_return 

這是我想如何做到這一點:

class ProjectPermalinkBaseMixIn(object): 
    """ 
    Project-specific Mix-In Class to `apps.base.models.PermalinkBase` 
    """ 

    @limit_to_model('Video') 
    def is_video_in_season(self, season): 
     videos_in_season = season.videos_in_this_season.all() 
     if self in list(videos_in_season): 
      to_return = True 
     else: 
      to_return = False 

     return to_return 

這是可能的裝飾? This answer幫助我更好地理解裝飾器,但我無法弄清楚如何修改它來解決上面列出的問題。

裝修工是否適合這份工作?如果是這樣,我將如何編寫裝飾器功能limit_to_model?如果不是,解決這個問題最好的辦法是什麼?

+3

爲什麼你想做的事這個?! – ThiefMaster

+1

我認爲你已經大量過度複雜的設計。只適用於某些類別的混音不是混音。只需創建一個抽象基類,然後在類中定義該功能即可。 (假定它是共享功能,在這種情況下,它看起來只需要是給定類中的函數)。 –

+0

另外,Yoda的邏輯是什麼?你檢查它是不是真的,然後在'else'情況下做你想要的。 –

回答

1

看着你的問題,我認爲這可能是一種過於複雜的方式來實現你正在嘗試做的事情。但是我寫了這段代碼:

def disallow_class(*klass_names): 
    def function_handler(fn): 
     def decorated(self, *args, **kwargs): 
      if self.__class__.__name__ in klass_names: 
       print "access denied to class: %s" % self.__class__.__name__ 
       return None 
      return fn(self, *args, **kwargs) 
     return decorated 
    return function_handler 


class MainClass(object): 

    @disallow_class('DisallowedClass', 'AnotherDisallowedClass') 
    def my_method(self, *args, **kwargs): 
     print "my_method running!! %s" % self 


class DisallowedClass(MainClass): pass 

class AnotherDisallowedClass(MainClass): pass 

class AllowedClass(MainClass): pass 


if __name__ == "__main__": 
    x = DisallowedClass() 
    y = AnotherDisallowedClass() 
    z = AllowedClass() 
    x.my_method() 
    y.my_method() 
    z.my_method() 

如果您在命令行中運行這段代碼的輸出將是這樣的:

access denied to class: DisallowedClass 
access denied to class: AnotherDisallowedClass 
my_method running!! <__main__.AllowedClass object at 0x7f2b7105ad50> 

問候

+0

太棒了!謝謝,@andrefsp ...我的裝飾知識已成倍增加!乾杯! – respondcreate

相關問題