Hướng dẫn python wrap class method - phương thức lớp bọc python

Tôi đang cố gắng tạo một đối tượng với một phương thức chạy sẽ được bọc bởi _wrap_run method. Tôi muốn có thể gọi phương thức và nó được bao bọc bằng cách nhập instance.run() và tôi muốn có thể phân lớp đối tượng để tôi có thể ghi đè phương thức run() và vẫn thực hiện trình bao bọc.

Nói một cách đơn giản hơn, tôi muốn mọi người có thể phân lớp A và ghi đè run() nhưng vẫn có các cuộc gọi đến phương thức run() thực hiện chức năng trình bao bọc.

Tôi đang gặp một số khó khăn với các cơ chế của việc này. Có ai có bất kỳ đề xuất liên quan đến phương pháp này?

class A:

    def run(self):
        print "Run A"
        return True

    def _wrap_run(self):
        print "PRE"
        return_value = self.run()
        print "POST"
        return return_value

    run = property(_wrap_run)


a = A()
a.run()
"""
Should Print: 
PRE
Run A
POST
"""


class B(A):

    def run(self):
        print "Run B"
        return True

b = B()
b.run()
"""
Should Print: 
PRE
Run B
POST
"""

Hướng dẫn python wrap class method - phương thức lớp bọc python

double-beep

4.60613 Huy hiệu vàng31 Huy hiệu bạc41 Huy hiệu đồng13 gold badges31 silver badges41 bronze badges

Đã hỏi ngày 21 tháng 7 năm 2011 lúc 18:31Jul 21, 2011 at 18:31

2

Sử dụng một metaclass.

class MetaClass(type):
    @staticmethod
    def wrap(run):
        """Return a wrapped instance method"""
        def outer(self):
            print "PRE",
            return_value = run(self)
            print "POST"
            return return_value
        return outer
    def __new__(cls, name, bases, attrs):
        """If the class has a 'run' method, wrap it"""
        if 'run' in attrs:
            attrs['run'] = cls.wrap(attrs['run'])
        return super(MetaClass, cls).__new__(cls, name, bases, attrs)

class MyClass(object):
    """Use MetaClass to make this class"""
    __metaclass__ = MetaClass
    def run(self): print 'RUN',

myinstance = MyClass()

# Prints PRE RUN POST
myinstance.run()

Bây giờ nếu những người khác phân nhóm MyClass, họ vẫn sẽ nhận được các phương pháp run() của họ.

Đã trả lời ngày 21 tháng 7 năm 2011 lúc 18:50Jul 21, 2011 at 18:50

Agfagfagf

165K41 Huy hiệu vàng281 Huy hiệu bạc232 Huy hiệu Đồng41 gold badges281 silver badges232 bronze badges

0

Cách dễ nhất: Làm cho

class MetaClass(type):
    @staticmethod
    def wrap(run):
        """Return a wrapped instance method"""
        def outer(self):
            print "PRE",
            return_value = run(self)
            print "POST"
            return return_value
        return outer
    def __new__(cls, name, bases, attrs):
        """If the class has a 'run' method, wrap it"""
        if 'run' in attrs:
            attrs['run'] = cls.wrap(attrs['run'])
        return super(MetaClass, cls).__new__(cls, name, bases, attrs)

class MyClass(object):
    """Use MetaClass to make this class"""
    __metaclass__ = MetaClass
    def run(self): print 'RUN',

myinstance = MyClass()

# Prints PRE RUN POST
myinstance.run()
1 thành trình bao bọc và một phương thức riêng tư là phương pháp có thể ghi đè.

class A(object):
    def run(self):
        print "PRE"
        return_value = self._inner_run()
        print "POST"
        return return_value

    def _inner_run(self):
        print "Run A"
        return True

class B(A):
    def _inner_run(self):
        print "Run B"
        return True

Đã trả lời ngày 21 tháng 7 năm 2011 lúc 18:36Jul 21, 2011 at 18:36

Cat Plus Plus Plus PlusCat Plus Plus

122K26 Huy hiệu vàng196 Huy hiệu bạc222 Huy hiệu đồng26 gold badges196 silver badges222 bronze badges

3

Những người khác làm gì

class A:
   def do_run( self ):
       """Must be overridden."""
       raise NotImplementedError
   def run( self, *args, **kw ):
       """Must not be overridden.
       You were warned.
       """
       print "PRE"
       return_value = self.do_run(*args, **kw)
       print "POST"
       return return_value

class B(A):
    def do_run(self):
        print "Run B"
        return True

Điều đó thường là đủ.

Nếu bạn muốn lo lắng về việc ai đó "phá vỡ" điều này, hãy dừng lại ngay bây giờ. Đừng lãng phí thời gian để lo lắng.

Đó là Python. Chúng ta đều là người lớn ở đây. Tất cả các xã hội độc hại sẽ phá vỡ tất cả các bạn mã bằng cách sao chép nó, thay đổi nó, và sau đó phá vỡ nó. Bất kể bạn làm gì, họ sẽ chỉ sao chép mã của bạn và sửa đổi nó để phá vỡ các bit thông minh.

Mọi người khác sẽ đọc bình luận của bạn và tuân theo các quy tắc của bạn. Nếu họ muốn sử dụng mô -đun/gói/khung của bạn, họ sẽ hợp tác.

Đã trả lời ngày 21 tháng 7 năm 2011 lúc 19:14Jul 21, 2011 at 19:14

S.LottS.LottS.Lott

378K79 Huy hiệu vàng503 Huy hiệu bạc773 Huy hiệu Đồng79 gold badges503 silver badges773 bronze badges

4

Những gì bạn có về cơ bản là một người trang trí, vậy tại sao không tiếp tục và thực hiện

class MetaClass(type):
    @staticmethod
    def wrap(run):
        """Return a wrapped instance method"""
        def outer(self):
            print "PRE",
            return_value = run(self)
            print "POST"
            return return_value
        return outer
    def __new__(cls, name, bases, attrs):
        """If the class has a 'run' method, wrap it"""
        if 'run' in attrs:
            attrs['run'] = cls.wrap(attrs['run'])
        return super(MetaClass, cls).__new__(cls, name, bases, attrs)

class MyClass(object):
    """Use MetaClass to make this class"""
    __metaclass__ = MetaClass
    def run(self): print 'RUN',

myinstance = MyClass()

# Prints PRE RUN POST
myinstance.run()
2 như một người trang trí và áp dụng nó khi phân lớp chức năng?

Đã trả lời ngày 21 tháng 7 năm 2011 lúc 18:37Jul 21, 2011 at 18:37

Gabi Purcarugabi PurcaruGabi Purcaru

30.3k9 Huy hiệu vàng76 Huy hiệu bạc92 Huy hiệu Đồng9 gold badges76 silver badges92 bronze badges

5