38

C++ では、子クラスでプライベートとして宣言することにより、親のクラスの関数を無効にすることができます。これはPythonでどのように行うことができますか? IE 子のパブリック インターフェイスから親の関数を非表示にするにはどうすればよいですか?

4

7 に答える 7

31

Python には、真の「プライベート」属性やメソッドはありません。できることの 1 つは、サブクラスで不要なメソッドを単純にオーバーライドして、例外を発生させることです。

>>> 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'
于 2008-10-23T22:52:51.513 に答える
19

b.foo問題を解決するkuroschの方法は完全に正しくありませんAttributeError。関数を呼び出さない場合、エラーは発生しません。これを行うために私が考えることができる2つの方法を次に示します。

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()

Bar は「wrap」パターンを使用して、ラップされたオブジェクトへのアクセスを制限します。Martelli はこれについて良い話をしています。Baz はプロパティ ビルトインを使用して、オーバーライドする属性の記述子プロトコルを実装します。

于 2008-10-25T00:05:19.717 に答える
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")
于 2008-10-23T22:49:22.863 に答える
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()
于 2014-04-17T06:32:24.403 に答える