Ger*_*ult 11 python scope nested-class
我已经看到了一些"解决方案",但每次解决方案似乎都是"不要使用嵌套类,在外面定义类,然后正常使用它们".我不喜欢这个答案,因为它忽略了我选择嵌套类的主要原因,也就是说,要创建一个可以访问所有子类实例的常量池(与基类相关联).
这是示例代码:
class ParentClass:
constant_pool = []
children = []
def __init__(self, stream):
self.constant_pool = ConstantPool(stream)
child_count = stream.read_ui16()
for i in range(0, child_count):
children.append(ChildClass(stream))
class ChildClass:
name = None
def __init__(self, stream):
idx = stream.read_ui16()
self.name = constant_pool[idx]
Run Code Online (Sandbox Code Playgroud)
所有类都传递一个param,这是一个自定义比特流类.我的目的是找到一个解决方案,它不需要我在ChildClass中读取ChildClass的idx值.所有子类流读取都应该在子类中完成.
这个例子过于简化了.常量池不是我需要的所有子类的唯一变量.idx变量不是从流阅读器读取的唯一内容.
这在python中甚至可能吗?有没有办法访问父母的信息?
kin*_*all 11
尽管我有点"赞美"评论(公平竞争称之为!),但实际上有办法实现你想要的东西:不同的继承途径.一对夫妇:
编写一个装饰器,它在声明类之后对其进行内省,找到内部类,并将外部类中的属性复制到它们中.
使用元类做同样的事情.
这是装饰器方法,因为它是最直接的:
def matryoshka(cls):
# get types of classes
class classtypes:
pass
classtypes = (type, type(classtypes))
# get names of all public names in outer class
directory = [n for n in dir(cls) if not n.startswith("_")]
# get names of all non-callable attributes of outer class
attributes = [n for n in directory if not callable(getattr(cls, n))]
# get names of all inner classes
innerclasses = [n for n in directory if isinstance(getattr(cls, n), classtypes)]
# copy attributes from outer to inner classes (don't overwrite)
for c in innerclasses:
c = getattr(cls, c)
for a in attributes:
if not hasattr(c, a):
setattr(c, a, getattr(cls, a))
return cls
Run Code Online (Sandbox Code Playgroud)
这是一个简单的使用示例:
@matryoshka
class outer(object):
answer = 42
class inner(object):
def __call__(self):
print self.answer
outer.inner()() # 42
Run Code Online (Sandbox Code Playgroud)
但是,我不禁想到其他答案中提出的一些想法会更好地为您服务.
你这里不需要两节课.这是您以更简洁的方式编写的示例代码.
class ChildClass:
def __init__(self, stream):
idx = stream.read_ui16()
self.name = self.constant_pool[idx]
def makeChildren(stream):
ChildClass.constant_pool = ConstantPool(stream)
return [ChildClass(stream) for i in range(stream.read_ui16())]
Run Code Online (Sandbox Code Playgroud)
欢迎使用Python.类在运行时是可变的.请享用.