Python的内部/嵌套类使我感到困惑.有没有它们无法实现的东西?如果是这样,那是什么东西?
引自http://www.geekinterview.com/question_details/64739:
内在阶级的优点:
类的逻辑分组:如果一个类只对另一个类有用,那么将它嵌入该类并将两者保持在一起是合乎逻辑的.嵌套这样的"帮助类"使得它们的包更加简化.
增加封装:考虑两个顶级类A和B,其中B需要访问A的成员,否则这些成员将被声明为私有.通过将类B隐藏在类AA中,可以将成员声明为私有,并且B可以访问它们.另外B本身可以隐藏在外面.
更易读,可维护的代码:在顶级类中嵌套小类会使代码更接近于使用它的位置.
主要优势是组织.任何可以通过内部类完成的事情都可以在没有它们的情况下完成.
有没有它们无法实现的东西?
不.它们绝对等同于通常在顶级定义类,然后将对它的引用复制到外部类中.
我认为没有任何特殊原因嵌套类是"允许的",除了明确"禁止"它们也没有特别意义.
如果你正在寻找一个存在于外部/所有者对象生命周期内的类,并且始终引用外部类的实例 - 内部类,就像Java那样 - 那么Python的嵌套类就不是那样了.但你可以破解类似的东西:
import weakref, new class innerclass(object): """Descriptor for making inner classes. Adds a property 'owner' to the inner class, pointing to the outer owner instance. """ # Use a weakref dict to memoise previous results so that # instance.Inner() always returns the same inner classobj. # def __init__(self, inner): self.inner= inner self.instances= weakref.WeakKeyDictionary() # Not thread-safe - consider adding a lock. # def __get__(self, instance, _): if instance is None: return self.inner if instance not in self.instances: self.instances[instance]= new.classobj( self.inner.__name__, (self.inner,), {'owner': instance} ) return self.instances[instance] # Using an inner class # class Outer(object): @innerclass class Inner(object): def __repr__(self): return '<%s.%s inner object of %r>' % ( self.owner.__class__.__name__, self.__class__.__name__, self.owner ) >>> o1= Outer() >>> o2= Outer() >>> i1= o1.Inner() >>> i1> >>> isinstance(i1, Outer.Inner) True >>> isinstance(i1, o1.Inner) True >>> isinstance(i1, o2.Inner) False
(这使用类装饰器,它是Python 2.6和3.0中的新增功能.否则你必须在类定义之后说"Inner = innerclass(Inner)".)
你需要有一些东西能够理解这一点.在大多数语言中,类定义是编译器的指令.也就是说,该类是在程序运行之前创建的.在python中,所有语句都是可执行的.这意味着这句话:
class foo(object): pass
是一个在运行时执行的语句,就像这样:
x = y + z
这意味着您不仅可以在其他类中创建类,还可以在任何地方创建类.考虑以下代码:
def foo(): class bar(object): ... z = bar()
因此,"内部阶级"的概念实际上并不是一种语言结构; 它是一个程序员构造.Guido对这里发生的事情进行了很好的总结.但实际上,基本思想是简化语言的语法.
在类中嵌套类:
嵌套类会使类定义膨胀,这使得查看最新情况变得更加困难.
嵌套类可以创建耦合,使测试更加困难.
在Python中,您可以在文件/模块中放置多个类,这与Java不同,因此该类仍然保持接近顶级类,甚至可以使用前缀为"_"的类名来帮助表示其他类不应该是使用它.
嵌套类可以证明有用的地方在函数内
def some_func(a, b, c): class SomeClass(a): def some_method(self): return b SomeClass.__doc__ = c return SomeClass
该类从函数中捕获值,允许您在C++中动态创建类似模板元编程的类
我了解反对嵌套类的参数,但是在某些情况下有使用它们的情况。想象一下,我正在创建一个双向链接列表类,并且需要创建一个节点类来维护节点。我有两个选择,在DoublyLinkedList类内部创建Node类,或在DoublyLinkedList类外部创建Node类。在这种情况下,我首选第一种选择,因为Node类仅在DoublyLinkedList类内部有意义。尽管没有隐藏/封装的好处,但是有一个好处就是可以说Node类是DoublyLinkedList类的一部分。