Наследование Python - как отключить функцию

python inheritance interface private

15531 просмотра

6 ответа

В C ++ вы можете отключить функцию в родительском классе, объявив ее закрытой в дочернем классе. Как это можно сделать в Python? IE Как я могу скрыть родительскую функцию от открытого интерфейса ребенка?

Автор: Boris Gorelik Источник Размещён: 26.06.2019 05:50

Ответы (6)


20 плюса

Решение

На самом деле в Python нет настоящих «приватных» атрибутов или методов. Одна вещь, которую вы можете сделать, это просто переопределить метод, который вам не нужен в подклассе, и вызвать исключение:

>>> class Foo( object ):
...     def foo( self ):
...         print 'FOO!'
...         
>>> class Bar( Foo ):
...     def foo( self ):
...         raise AttributeError( "'Bar' object has no attribute 'foo'" )
...     
>>> b = Bar()
>>> b.foo()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
  File "<interactive input>", line 3, in foo
AttributeError: 'Bar' object has no attribute 'foo'
Автор: kurosch Размещён: 23.10.2008 10:52

17 плюса

Метод решения проблемы, предложенный kurosch, не совсем корректен, потому что вы все равно можете использовать его b.fooбез получения AttributeError. Если вы не вызываете функцию, ошибки не возникает. Вот два способа, которыми я могу подумать, чтобы сделать это:

import doctest

class Foo(object):
    """
    >>> Foo().foo()
    foo
    """
    def foo(self): print 'foo'
    def fu(self): print 'fu'

class Bar(object):
    """
    >>> b = Bar()
    >>> b.foo()
    Traceback (most recent call last):
    ...
    AttributeError
    >>> hasattr(b, 'foo')
    False
    >>> hasattr(b, 'fu')
    True
    """
    def __init__(self): self._wrapped = Foo()

    def __getattr__(self, attr_name):
        if attr_name == 'foo': raise AttributeError
        return getattr(self._wrapped, attr_name)

class Baz(Foo):
    """
    >>> b = Baz()
    >>> b.foo() # doctest: +ELLIPSIS
    Traceback (most recent call last):
    ...
    AttributeError...
    >>> hasattr(b, 'foo')
    False
    >>> hasattr(b, 'fu')
    True
    """
    foo = property()

if __name__ == '__main__':
    doctest.testmod()

Бар использует шаблон «обтекание», чтобы ограничить доступ к обернутому объекту. Мартелли хорошо поговорил об этом. Baz использует встроенное свойство для реализации протокола дескриптора для переопределения атрибута.

Автор: cdleary Размещён: 25.10.2008 12:05

10 плюса

Вариант ответа от kurosch:

class Foo( object ):
    def foo( self ):
        print 'FOO!'

class Bar( Foo ):
    @property
    def foo( self ):
        raise AttributeError( "'Bar' object has no attribute 'foo'" )

b = Bar()
b.foo

Это вызывает AttributeErrorсвойство вместо того, когда вызывается метод.

Я бы предложил это в комментарии, но, к сожалению, пока не пользуюсь репутацией.

Автор: John Damen Размещён: 17.04.2014 06:41

5 плюса

class X(object):
    def some_function(self):
        do_some_stuff()

class Y(object):
    some_function = None

Это может привести к появлению некоторых неприятных и трудных для поиска исключений, поэтому вы можете попробовать это:

class X(object):
    def some_function(self):
        do_some_stuff()

class Y(object):
    def some_function(self):
        raise NotImplementedError("function some_function not implemented")
Автор: Jason Baker Размещён: 23.10.2008 10:49

1 плюс

Это самый чистый способ, которым я знаю, чтобы сделать это.

Переопределите методы, и каждый из переопределенных методов вызовет ваш метод disabledmethods (). Как это:

class Deck(list):
...
@staticmethod
    def disabledmethods():
        raise Exception('Function Disabled')
    def pop(self): Deck.disabledmethods()
    def sort(self): Deck.disabledmethods()
    def reverse(self): Deck.disabledmethods()
    def __setitem__(self, loc, val): Deck.disabledmethods()
Автор: Joey Nelson Размещён: 17.04.2014 06:32

0 плюса

Это может быть еще проще.

@property
def private(self):
    raise AttributeError

class A:
    def __init__(self):
        pass
    def hello(self):
        print("Hello World")

class B(A):
    hello = private # that short, really
    def hi(self):
        A.hello(self)

obj = A()
obj.hello()
obj = B()
obj.hi() # works
obj.hello() # raises AttributeError
Автор: Денис Колесников Размещён: 26.06.2019 10:59
Вопросы из категории :
32x32