0

クラス Bar は Foo から継承します。

class Foo(object):
      def foo_meth_1(self):
          return 'foometh1'
      def foo_meth_2(self):
          return 'foometh2'
class Bar(Foo):
      def bar_meth(self):
          return 'bar_meth'

Foo から継承されたすべてのメソッドを非公開にする方法はありますか?

class Bar(Foo):
      def bar_meth(self):
          return 'bar_meth'
      def __foo_meth_1(self):
          return 'foometh1'
      def __foo_meth_2(self):
          return 'foometh2'
4

4 に答える 4

3

Python にはプライベートはなく、難読化されたメソッド名のみがあります。しかし、インスタンスを作成するときにスーパークラスのメソッドを繰り返し処理し、それらを自分自身から削除して、それらの関数の難読化された名前の新しいメソッド名を作成できると思います。setattr と getattr は、関数を使用して難読化された名前を作成する場合に役立ちます。

そうは言っても、それはかなりcthuhlu-oidのことです。名前空間をきれいに保つことが目的だとおっしゃっていますが、これはアンモニアと塩素を混ぜるようなものです。メソッドを非表示にする必要がある場合は、スーパークラスで非表示にします。スーパークラスのインスタンスを作成しないでください。代わりに、非表示のメソッドをパブリック メソッドにラップする特定のクラスを作成します。これには同じ名前を付けることができますが、先頭の空白を削除できます。

あなたの意図を正しく理解していると仮定すると、次のようなことをお勧めします。

class BaseFoo(object):
    def __init__(self):
        raise NotImplementedError('No instances of BaseFoo please.')
    def _foo(self):
        return 'Foo.'
    def _bar(self):
        return 'Bar.'

class HiddenFoo(BaseFoo):
    def __init__(self): pass

class PublicFoo(BaseFoo):
    def __init__(self): pass
    foo = BaseFoo._foo
    bar = BaseFoo._bar

def try_foobar(instance):
    print 'Trying ' + instance.__class__.__name__
    try:
        print 'foo: ' + instance.foo
        print 'bar: ' + instance.bar
    except AttributeError, e:
        print e

foo_1 = HiddenFoo()
foo_2 = PublicFoo()
try_foobar(foo_1)
try_foobar(foo_2)

そして、PublicFoo.foo以上のことを行う場合はBaseFoo.foo、必要なことを何でも行うラッパーを作成し、スーパークラスから foo を呼び出します。

于 2012-09-14T11:00:30.543 に答える
2

これは、Pyhtons のメタクラスでのみ可能です。しかし、これは非常に洗練されたものであり、努力する価値があるかどうかはわかりません。詳細は こちらをご覧ください

なぜそうしたいのですか?

于 2012-09-14T10:52:41.633 に答える
0

メタクラスを使用できますが、のインスタンスで'メソッドを'private'と'public'の両方にしBooたい場合を除いて、Fooの実際のサブクラスではなくなります(親クラスから継承された名前またはメンバーを選択的に継承することはできません)。これは非常に工夫された例です:FooBardelattr

from inspect import getmembers, isfunction

class TurnPrivateMetaclass(type):
    def __new__(cls, name, bases, d):
        private = {'__%s' % i:j for i,j in getmembers(bases[0]) if isfunction(j)}
        d.update(private)

        return type.__new__(cls, name, (), d)

class Foo:
    def foo_meth_1(self): return 'foometh1'
    def foo_meth_2(self): return 'foometh2'

class Bar(Foo, metaclass=TurnPrivateMetaclass):
    def bar_meth(self): return 'bar_meth'

b = Bar()
assert b.__foo_meth_1() == 'foometh1'
assert b.__foo_meth_2() == 'foometh2'
assert b.bar_meth() == 'bar_meth

属性アクセスを機能させたい場合は、名前を変更したすべてのメソッドを削除して、で新しいFoo基本クラスを作成できます。__new__

于 2012-09-14T11:46:31.290 に答える
0

foo()とは完全に異なるメソッドであり、それらの間にリンクがないため__foo()、Python は何をしたいのか理解できません。したがって、古い方法を削除して新しい方法を追加することを意味する(sapthが言ったように)段階的に説明する必要があります。

これはオブジェクト指向設計の欠陥であり、より良いアプローチは委任によるものです。

class Basic:
    def meth_1(self):
        return 'meth1'

    def meth_2(self):
        return 'meth2'


class Foo(Basic):
    # Nothing to do here
    pass


class Bar:
    def __init__(self):
        self.dg = Basic()

    def bar_meth(self):
        return 'bar_meth ' + self.__meth_1()

    def __meth_1(self):
        return self.dg.meth_1()

    def __meth_2(self):
        return self.dg.meth_2()

は彼からパブリック メソッドを取得したいのでクラスをFoo継承しますが、 のインターフェイスを独自のインターフェイスに統合したくないため、ジョブを に委任するだけです。BasicBarBasicBasic

于 2012-09-14T11:53:32.243 に答える