zeromq:TypeError:字符串索引必须是整数,而不是 str

Posted

技术标签:

【中文标题】zeromq:TypeError:字符串索引必须是整数,而不是 str【英文标题】:zeromq: TypeError: string indices must be integers, not str 【发布时间】:2014-10-13 03:30:54 【问题描述】:

我想在机器之间建立发布订阅通信。

我拥有的两台机器是ryu-primaryryu-secondary

我在每台机器中遵循的步骤如下。

ryu-primary的初始化器中(IP地址是192.168.241.131)

 self.context    = zmq.Context()
 self.sub_socket = self.context.socket(zmq.SUB)
 self.pub_socket = self.context.socket(zmq.PUB)
 self.pub_port   = 5566
 self.sub_port   = 5566


def establish_zmq_connection(self):                      # Socket to talk to server
    print( "Connection to ryu-secondary..." )
    self.sub_socket.connect( "tcp://192.168.241.132:%s" % self.sub_port )

def listen_zmq_connection(self):
    print( 'Listen to zmq connection' )
    self.pub_socket.bind( "tcp://*:%s" % self.pub_port )

def recieve_messages(self):
    while True:
        try:
            string = self.sub_socket.recv( flags=zmq.NOBLOCK )
            print( 'flow mod messages recieved '.format(string) )
            return string
        except zmq.ZMQError:
            break

def push_messages(self,msg):
    self.pub_socket.send( "%s" % (msg) )

来自 ryu-secondary(IP 地址 - 192.168.241.132)

在初始化器中

    self.context    = zmq.Context()
    self.sub_socket = self.context.socket(zmq.SUB)
    self.pub_socket = self.context.socket(zmq.PUB)
    self.pub_port   = 5566
    self.sub_port   = 5566


def establish_zmq_connection(self):                     # Socket to talk to server
     print( "Connection to ryu-secondary..." )
     self.sub_socket.connect( "tcp://192.168.241.131:%s" % self.sub_port )

def listen_zmq_connection(self):
     print( 'Listen to zmq connection' )
     self.pub_socket.bind( "tcp://*:%s" % self.pub_port )

def recieve_messages(self):
    while True:
        try:
            string = self.sub_socket.recv( flags=zmq.NOBLOCK )
            print( 'flow mod messages recieved '.format(string) )
            return string
        except zmq.ZMQError:
            break

def push_messages(self,msg):
    print( 'pushing message to publish socket' )
    self.pub_socket.send( "%s" % (msg) )

这些是我拥有的功能。

我打电话给ryu-secondary

establish_zmq_connections()
push_messages() 

ryu-primary,当我打电话时

listen_zmq_connection()
recieve_messages() 

使用.setsockopt( zmq.SUBSCRIBE = '')

订阅所有类型的消息之后

但是我尝试发送的消息属于以下类型。

msg = 'in_port':in_port,'dst':dst,'actions':actions
self.push_messages(msg)

但是另一方面(recieve_messages() 执行此操作时出现以下错误

flow_mod = recieve_messages() 

flow_mod['in_port']
flow_mod['dst']
flow_mod['actions']


TypeError: string indices must be integers, not str

【问题讨论】:

@WarrenWeckesser - 我想访问该字典中包含的信息,即键 'in_port'、'dst' 和 'actions' 的值 【参考方案1】:

msg 是一个 Python 字典,但您正在发送(和接收)格式化为字符串的消息。可能最简单的做法是将msg 序列化为 JSON 格式,将其作为字符串发送,然后将接收到的字符串再次加载回字典。然后,只有这样,您才能正确访问键和值。像这样的东西应该可以工作(确保你在上面某处import json):

# on the sending end
msg = 'in_port':in_port,'dst':dst,'actions':actions
msg_string = json.dumps(msg)
self.push_messages(msg)

# on the receiving end
payload = receive_messages()
message = json.loads(payload)

您可以找到 json 模块 here(适用于 Python 2)和 here 适用于 Python 3 的完整文档。

【讨论】:

谢谢你的回复。你能解释一下怎么做吗。我对python不是很精通吗?【参考方案2】:

ZeroMQ API 背景

ZeroMQ .send() .recv() 方法对字符串进行操作。你向他们传递一个他们不知道如何处理的字典对象。将字典对象转换为 JSON 格式,作为针对这种情况的序列化示例,您的工作就完成了。

答案 = 得到 TypeError 的原因是什么?

正如所写,ZeroMQ 的 .send() 方法在发送它不理解的对象方面并不能做太多事情,并且 .recv() 部分仍然读取在 ZeroMQ 层上传递的任何内容。

因此,您的 flow_mod 变量正确地接收 string 作为函数 return string 指令中的 recieve_messages() 订单。

string = self.sub_socket.recv( flags=zmq.NOBLOCK ) 只提供任何字符串,无论是空字符串还是从套接字另一侧接收的任何非零长度字符串。

最后: flow_mod['in_port'] 将在语法上崩溃(并且必须这样做),因为变量 flow_mod 的内容,在此之前分配和类型调整,没有类似字典的访问方法来处理这个语法类型。

因此必须在此处引发 TypeError: string indices must be integers, not str 异常。

Q.E.D.


对象的 JSON 序列化表示 - 编码和解码介绍:

>>> import json
>>> print json.__doc__
JSON (javascript Object Notation) <http://json.org> is a subset of
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
interchange format.

[json] exposes an API familiar to users of the standard library
[marshal] and [pickle] modules. It is the externally maintained
version of the [json] library contained in Python 2.6, but maintains
compatibility with Python 2.4 and Python 2.5 and (currently) has
significant performance advantages, even without using the optional C
extension for speedups.

Encoding basic Python object hierarchies::

    >>> import json
    >>> json.dumps(['foo', 'bar': ('baz', None, 1.0, 2)])
    '["foo", "bar": ["baz", null, 1.0, 2]]'
    >>> print json.dumps("\"foo\bar")
    "\"foo\bar"
    >>> print json.dumps(u'\u1234')
    "\u1234"
    >>> print json.dumps('\\')
    "\\"
    >>> print json.dumps("c": 0, "b": 0, "a": 0, sort_keys=True)
    "a": 0, "b": 0, "c": 0
    >>> from StringIO import StringIO
    >>> io = StringIO()
    >>> json.dump(['streaming API'], io)
    >>> io.getvalue()
    '["streaming API"]'

Compact encoding::

    >>> import json
    >>> json.dumps([1,2,3,'4': 5, '6': 7], sort_keys=True, separators=(',',':'))
    '[1,2,3,"4":5,"6":7]'

Pretty printing::

    >>> import json
    >>> print json.dumps('4': 5, '6': 7, sort_keys=True,
    ...                  indent=4, separators=(',', ': '))
    
        "4": 5,
        "6": 7
    

Decoding JSON::

    >>> import json
    >>> obj = [u'foo', u'bar': [u'baz', None, 1.0, 2]]
    >>> json.loads('["foo", "bar":["baz", null, 1.0, 2]]') == obj
    True
    >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
    True
    >>> from StringIO import StringIO
    >>> io = StringIO('["streaming API"]')
    >>> json.load(io)[0] == 'streaming API'
    True

Specializing JSON object decoding::

    >>> import json
    >>> def as_complex(dct):
    ...     if '__complex__' in dct:
    ...         return complex(dct['real'], dct['imag'])
    ...     return dct
    ...
    >>> json.loads('"__complex__": true, "real": 1, "imag": 2',
    ...     object_hook=as_complex)
    (1+2j)
    >>> from decimal import Decimal
    >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
    True

Specializing JSON object encoding::

    >>> import json
    >>> def encode_complex(obj):
    ...     if isinstance(obj, complex):
    ...         return [obj.real, obj.imag]
    ...     raise TypeError(repr(o) + " is not JSON serializable")
    ...
    >>> json.dumps(2 + 1j, default=encode_complex)
    '[2.0, 1.0]'
    >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
    '[2.0, 1.0]'
    >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
    '[2.0, 1.0]'

【讨论】:

谢谢你的回复。你能解释一下怎么做吗。我对python不是很精通吗? 直接投反对票?告诉我为什么勇敢的匿名反对者,这是平庸的做法...... 我按下了对系统的反对票:(我已经恢复了它。一旦它起作用就会赞成:) @liv2hak 你的 -1/+1 没问题,但在你之前还有另一个反对票。

以上是关于zeromq:TypeError:字符串索引必须是整数,而不是 str的主要内容,如果未能解决你的问题,请参考以下文章

读取 JSON 字符串 | TypeError:字符串索引必须是整数

Python:TypeError:字符串索引必须是整数[关闭]

弹性搜索 | TypeError:字符串索引必须是整数

TypeError:字符串索引必须是整数 Python 2

为啥在尝试从 api 获取数据时出现此错误“TypeError:字符串索引必须是整数”?

TypeError:使用Python解析JSON时字符串索引必须是整数?