python中的递归类和thrift中的一个bug
Thrift 0.9.2现在允许包含自身实例的递归结构。例如,这个节俭定义:python中的递归类和thrift中的一个bug,python,c,recursion,thrift,Python,C,Recursion,Thrift,Thrift 0.9.2现在允许包含自身实例的递归结构。例如,这个节俭定义: namespace py foo struct Foo { 1: optional string member 2: optional Foo fooData } 生成以下代码: # # Autogenerated by Thrift Compiler (0.9.2) # # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOI
namespace py foo
struct Foo {
1: optional string member
2: optional Foo fooData
}
生成以下代码:
#
# Autogenerated by Thrift Compiler (0.9.2)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
# options string: py
#
from thrift.Thrift import TType, TMessageType, TException, TApplicationException
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol, TProtocol
try:
from thrift.protocol import fastbinary
except:
fastbinary = None
class Foo:
"""
Attributes:
- member
- fooData
"""
thrift_spec = (
None, # 0
(1, TType.STRING, 'member', None, None, ), # 1
(2, TType.STRUCT, 'fooData', (Foo, Foo.thrift_spec), None, ), # 2
)
def __init__(self, member=None, fooData=None,):
self.member = member
self.fooData = fooData
def read(self, iprot):
if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec))
return
iprot.readStructBegin()
while True:
(fname, ftype, fid) = iprot.readFieldBegin()
if ftype == TType.STOP:
break
if fid == 1:
if ftype == TType.STRING:
self.member = iprot.readString();
else:
iprot.skip(ftype)
elif fid == 2:
if ftype == TType.STRUCT:
self.fooData = Foo()
self.fooData.read(iprot)
else:
iprot.skip(ftype)
else:
iprot.skip(ftype)
iprot.readFieldEnd()
iprot.readStructEnd()
def write(self, oprot):
if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None:
oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec)))
return
oprot.writeStructBegin('Foo')
if self.member is not None:
oprot.writeFieldBegin('member', TType.STRING, 1)
oprot.writeString(self.member)
oprot.writeFieldEnd()
if self.fooData is not None:
oprot.writeFieldBegin('fooData', TType.STRUCT, 2)
self.fooData.write(oprot)
oprot.writeFieldEnd()
oprot.writeFieldStop()
oprot.writeStructEnd()
def validate(self):
return
def __hash__(self):
value = 17
value = (value * 31) ^ hash(self.member)
value = (value * 31) ^ hash(self.fooData)
return value
def __repr__(self):
L = ['%s=%r' % (key, value)
for key, value in self.__dict__.iteritems()]
return '%s(%s)' % (self.__class__.__name__, ', '.join(L))
def __eq__(self, other):
return isinstance(other, self.__class__) and self.__dict__ == other.__dict__
def __ne__(self, other):
return not (self == other)
此代码的问题在于类变量节俭\u spec
:
thrift_spec = (
None, # 0
(1, TType.STRING, 'member', None, None, ), # 1
(2, TType.STRUCT, 'fooData', (Foo, Foo.thrift_spec), None, ), # 2
)
这里有两个问题:
Foo
(实例化时将产生NameError:name'Foo'未定义
)thrift_spec
试图包含对自身的引用,这在python中是一件奇怪的事情(自引用元组?)无法通过标准的Python级api构建这样的元组,即使您直接与C api混淆,它也会破坏一切,因为Python假定元组不会是这样。除了元组之外,还有没有可能在
节俭规范
中使用其他东西呢?是的,我认为这是一种方法。我可能会尝试使用我在C-module中寻找的一些sentinel值,这意味着获取对我自己的引用。通过标准Python级api无法构建这样的元组,即使直接与C-api混淆,它也会破坏一些东西,因为Python假定元组不能这样。除了元组之外,还有没有可能在节俭规范
中使用其他东西呢?是的,我认为这是一种方法。我可能会尝试使用我在C-module中寻找的一些sentinel值,这意味着获得对我自己的引用。