Class 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'
答案 0 :(得分:3)
Python没有私有,只有混淆的方法名称。但是我想你可以在创建实例时迭代超类的方法,从自己中删除它们并为这些函数创建新的混淆命名的方法名称。如果使用函数创建模糊名称,setattr和getattr可能很有用。
据说,这是一个非常好的事情。你提到的目的是保持命名空间更清洁,但这更像是混合氨和氯。如果需要隐藏该方法,请将其隐藏在超类中。不要创建超类的实例 - 而是创建一个特定的类,将隐藏的方法包装在公共类中,你可以命名相同的东西,但剥离前导空格。
假设我理解你的意图,我会建议做这样的事情:
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。
答案 1 :(得分:2)
这只适用于Pyhtons的元类。但这很复杂,我不确定是否值得付出努力。有关详细信息,请查看here
你为什么要这样做?
答案 2 :(得分:0)
您可以使用元类,但Boo
将不再是Foo的实际子类,除非您希望Foo
的方法在{{的实例中同时为'private'和'public' 1}}(您无法有选择地继承从父类继承的名称或Bar
成员)。这是一个非常人为的例子:
delattr
如果您希望让属性访问工作,可以在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
基类,并删除所有重命名的方法。
答案 3 :(得分: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
继承了Basic
类,因为他想要来自他的公共方法,Bar
只会将作业委托给Basic
,因为他不想整合Basic
进入自己界面的界面。