python 内部类调用外部类变量,嵌套的Python类需要访问封闭类中的变量

本文探讨了如何使用Python装饰器解决在类中访问父类属性的问题,提供了一种无需直接读取子类属性的方法,并通过示例代码展示了装饰器的具体实现。

I've seen a few "solutions" to this, but the solution every time seems to be "Don't use nested classes, define the classes outside and then use them normally". I don't like that answer, because it ignores the primary reason I chose nested classes, which is, to have a pool of constants (associated with the base class) accessible to all sub-class instances which are created.

Here is example code:

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]

All classes are passed a single param, which is a custom bitstream class. My intention is to have a solution that does not require me to read the idx value for ChildClass while still in the ParentClass. All child-class stream reading should be done in the child class.

This example is over simplified. The constant pool is not the only variable i need available to all subclasses. The idx variable is not the only thing read from the stream reader.

Is this even possible in python? Is there no way to access the parent's information?

解决方案

Despite my "bit patronizing" comment (fair play to call it that!), there are actually ways to achieve what you want: a different avenue of inheritance. A couple:

Write a decorator that introspects a class just after it's declared, finds inner classes, and copies attributes from the outer class into them.

Do the same thing with a metaclass.

Here's the decorator approach, since it's the most straightforward:

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

Here is a simple example of its use:

@matryoshka

class outer(object):

answer = 42

class inner(object):

def __call__(self):

print self.answer

outer.inner()() # 42

However, I can't help but think some of the ideas suggested in other answers would serve you better.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值