Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的递归类和thrift中的一个bug_Python_C_Recursion_Thrift - Fatal编程技术网

python中的递归类和thrift中的一个bug

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

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 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
  )
这里有两个问题:

  • 类def在完全定义之前尝试引用
    Foo
    (实例化时将产生
    NameError:name'Foo'未定义
  • thrift_spec
    试图包含对自身的引用,这在python中是一件奇怪的事情(自引用元组?)
  • 这个元组由thrift中名为fastbinary的包使用,fastbinary是一个以本机方式序列化和反序列化thrift对象的C模块。元组用于将类型信息传递给C模块

    我的问题是如何最好地解决这两个问题。对于#1,我可以将thrift#u规范的实例化移动到类定义之后,或者将其移动到@property中。我真的不知道该怎么办。有没有办法获取对tuple对象的引用并将其传递给C模块

    请注意,这是我希望帮助解决的节俭中的一个公开错误:

    无法通过标准的Python级api构建这样的元组,即使您直接与C api混淆,它也会破坏一切,因为Python假定元组不会是这样。除了元组之外,还有没有可能在
    节俭规范
    中使用其他东西呢?是的,我认为这是一种方法。我可能会尝试使用我在C-module中寻找的一些sentinel值,这意味着获取对我自己的引用。通过标准Python级api无法构建这样的元组,即使直接与C-api混淆,它也会破坏一些东西,因为Python假定元组不能这样。除了元组之外,还有没有可能在
    节俭规范
    中使用其他东西呢?是的,我认为这是一种方法。我可能会尝试使用我在C-module中寻找的一些sentinel值,这意味着获得对我自己的引用。