【发布时间】:2016-09-10 21:36:08
【问题描述】:
我想做一些绝对不符合 Python 的事情。我想创建一个允许前向声明其类属性的类。 (如果你必须知道,我正在尝试为解析器组合器制作一些甜美的语法。)
这就是我想做的事情:
a = 1
class MyClass(MyBaseClass):
b = a # Refers to something outside the class
c = d + b # Here's a forward declaration to 'd'
d = 1 # Declaration resolved
我当前的方向是创建一个元类,这样当找不到d 时,我会捕获NameError 异常并返回一个我将调用ForwardDeclaration 的虚拟类的实例。我从AutoEnum 中获得了一些灵感,它使用元类魔法来声明带有裸标识符且没有赋值的枚举值。
以下是我目前所拥有的。缺少的部分是:我如何继续正常的名称解析并捕获NameErrors:
class MetaDict(dict):
def __init__(self):
self._forward_declarations = dict()
def __getitem__(self, key):
try:
### WHAT DO I PUT HERE ??? ###
# How do I continue name resolution to see if the
# name already exists is the scope of the class
except NameError:
if key in self._forward_declarations:
return self._forward_declarations[key]
else:
new_forward_declaration = ForwardDeclaration()
self._forward_declarations[key] = new_forward_declaration
return new_forward_declaration
class MyMeta(type):
def __prepare__(mcs, name, bases):
return MetaDict()
class MyBaseClass(metaclass=MyMeta):
pass
class ForwardDeclaration:
# Minimal behavior
def __init__(self, value=0):
self.value = value
def __add__(self, other):
return ForwardDeclaration(self.value + other)
【问题讨论】:
-
你不能通过使用默认参数(在这种情况下为属性)来解决这个问题吗?
-
除非我误解了你,否则那是行不通的,因为我在定义
MyBaseClass时不知道MyClass的属性是什么。如果我这样做了,那你就是对的;我可以在基类中像d = ForwardDeclaration()一样声明它们。 -
这听起来非常恶心!做得好!目前尚不清楚具体问题/问题是什么?
标签: python python-3.x metaclass