Python类:将所有继承的方法变为私有
类栏从Foo继承:Python类:将所有继承的方法变为私有,python,class,Python,Class,类栏从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):
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'
这只有在Pythons的元类中才可能实现。但这是相当复杂的,我不确定是否值得努力。详情请看一看
为什么要这样做?这只适用于Pyhtons的元类。但这是相当复杂的,我不确定是否值得努力。详情请看一看
为什么要这样做?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。Python没有private,只有模糊的方法名。但我认为,在创建实例时,您可以迭代超类的方法,将它们从自己身上删除,并为这些函数创建新的模糊命名的方法名。如果使用函数创建模糊名称,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。您可以使用元类,但Boo
将不再是foo的实际子类,除非您希望Foo
的方法在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
如果你想让属性访问正常工作,你可以在
\uuuuuuuuuuuuu
中创建一个新的Foo
基类,删除所有重命名的方法。你可以使用元类,但是Boo
将不再是Foo的实际子类,除非您希望Foo
的方法在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
如果您想让属性访问正常工作,可以在\uuu new\uuu
中创建一个新的Foo
基类,删除所有重命名的方法。由于Foo()
和\uu 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
的接口集成到自己的接口中。因为Foo()
和\ufoo()
是完全不同的方法,它们之间没有链接,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
的接口集成到它自己的接口中。如果隐藏Foo的方法,你就不是一个很好的Foo。如果你想这样做,最好是简单地拥有一个Bar
实例,而不是从是吗?@约阿希姆·绍尔——同意,这只是一个例子。我正试图深入研究类,了解什么可以做,什么不能做。适配器不是比继承更好的解决方案吗?@Tim Hoffman--我将研究它,谢谢。如果你隐藏了Foo的方法,你就不会是一个很好的Foo。如果你想这样做,简单地拥有一个Bar
实例,而不是从它继承,不是更好吗?@约阿希姆·绍尔——同意,这只是一个例子。我试图深入研究类,了解什么可以做,什么不能做。适配器不是比继承更好的解决方案吗。@蒂姆·霍夫曼——我会研究它,谢谢。它是你自己的本地名称空间,所以我看不出你会如何“污染”它。但是无论如何,如果您将方法名更改为私有名称,则原始类的所有内部方法调用都需要