【问题标题】:PYTHON for loop through dict_keys and UDP sendPYTHON for 循环通过 dict_keys 和 UDP 发送
【发布时间】:2013-12-25 17:51:19
【问题描述】:

作为一个对 Python 几乎一无所知的 Pascal 程序员,我正在尝试使用 pyicloud https://github.com/picklepete/pyicloud/ 编写一个小而简单的 Python 脚本,该脚本每隔某某秒通过 UDP 套接字重定向所有设备的位置数据 json输出如底部所示。 python 脚本应该是这样的:

from pyicloud import PyiCloudService
api = []
api.append(PyiCloudService('JAppleseedAppleIdEmailHere', 'password'))
api.append(PyiCloudService('SomeOtherAppleIdEmailHere', 'psadfsdfassword')) 
# more accounts here if desired...
#PeerIp = '10.0.0.5'
PeerIp = '127.0.0.1'
PeerPort = 2028

import time, threading, socket, json, struct

ContinueDevicesPostionUpdate = True

def DevicesPostionUpdate():
    if ContinueDevicesPostionUpdate:
        # print(time.ctime())
        threading.Timer(10, DevicesPostionUpdate).start()

        # Code for generating json from api.devices and api.devices[].location()
        # This is where i get all sort of errors in my shotgun programming
        MESSAGE = bytes(smsg, 'utf-8')
        sock.sendto(MESSAGE, (PeerIp, PeerPort))

sock = socket.socket(socket.AF_INET,        # Internet
                     socket.SOCK_DGRAM)     # UDP
DevicesPostionUpdate()

例如:

for k, v in api:
    for key, value in api[k].devices.items():
        print (api[k].devices[key].location())
#results in:
Exception in thread Thread-4:
Traceback (most recent call last):
  File "C:\Python33\lib\threading.py", line 901, in _bootstrap_inner
    self.run()
  File "C:\Python33\lib\threading.py", line 1142, in run
    self.function(*self.args, **self.kwargs)
  File "test.py", line 17, in DevicesPostionUpdate
    for k, v in api:
TypeError: 'PyiCloudService' object is not iterable

或者

MESSAGE = json.dumps([dict(device=device, location=device.location()) for a in api for device in a.devices.values()]).encode()
#results in:
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    DevicesPostionUpdate()
  File "test.py", line 17, in DevicesPostionUpdate
    MESSAGE = json.dumps([dict(device=device, location=device.location()) for a in api for device in a.devices.values()]).encode()
  File "C:\Python33\lib\json\__init__.py", line 236, in dumps
    return _default_encoder.encode(obj)
  File "C:\Python33\lib\json\encoder.py", line 191, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Python33\lib\json\encoder.py", line 249, in iterencode
    return _iterencode(o, 0)
  File "C:\Python33\lib\json\encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <AppleDevice(iPhone 4S: Johnny Appleseed's iPhone)> is not JSON serializable

期望的输出应该是这样的:

{
    {
        u'i9vbKRGIcLYqJnXMd1b257kUWnoyEBcEh6yM+IfmiMLh7BmOpALS+w==': <AppleDevice(iPhone 4S: Johnny Appleseed's iPhone)>,
        {   
        u'timeStamp': 1357753796553, 
        u'locationFinished': True, 
        u'longitude': -0.14189, 
        u'positionType': u'GPS', 
        u'locationType': None, 
        u'latitude': 51.501364, 
        u'isOld': False, 
        u'horizontalAccuracy': 5.0
        }
    }
    ,
    {
    u'reGYDh9XwqNWTGIhNBuEwP1ds0F/Lg5t/fxNbI4V939hhXawByErk+HYVNSUzmWV': <AppleDevice(MacBook Air 11": Johnny Appleseed's MacBook Air)>
        {   
        u'timeStamp': 1357753796553, 
        u'locationFinished': True, 
        u'longitude': -0.14189, 
        u'positionType': u'GPS', 
        u'locationType': None, 
        u'latitude': 51.501364, 
        u'isOld': False, 
        u'horizontalAccuracy': 5.0
        }
    }
    ,
    {
    u'reGYDh9XwqNWTGIhNBuEwP1ds0F/Lg5t/fxNbI4V939hhXawByErk+HYVNSUzmWV': <AppleDevice(iPhone 4S: Some Other's iPhone)>
        {   
        u'timeStamp': 1357753796553, 
        u'locationFinished': True, 
        u'longitude': -0.14189, 
        u'positionType': u'GPS', 
        u'locationType': None, 
        u'latitude': 51.501364, 
        u'isOld': False, 
        u'horizontalAccuracy': 5.0
        }
    }
}

如果您不想在这里帮助我,您可以随时通过在 freelancer.com 上展示您的解决方案来赚取 30 美元

【问题讨论】:

    标签: python arrays json sockets for-loop


    【解决方案1】:

    您似乎正在使用 python 3。用于 dicts 的 .iteritems() 方法不再存在,它已被 .items() 取代。尝试更换它,看看是否有帮助。

    【讨论】:

    • 对一些人有帮助。然而只是遇到了新问题:D
    • 有什么新问题?
    【解决方案2】:

    没有什么比提出问题并在几个小时后自己得到答案更有趣的了。感谢您的帮助Totem

    你是个天才J.F. Sebastian

    from pyicloud import PyiCloudService
    api = []
    api.append(PyiCloudService('JAppleseedAppleIdEmailHere', 'password'))
    api.append(PyiCloudService('SomeOtherAppleIdEmailHere', 'psadfsdfassword'))
    PeerIp = '127.0.0.1'
    PeerPort = 2028
    ThreadRunCount = -1
    InfoEveryRunTime = 10
    import time, threading, socket, json
    def update_device_position():
        smsg = '{\n'
        global ThreadRunCount
        ThreadRunCount += 1
        MESSAGE = json.dumps([dict(device=str(device), location=device.location()) for a in api for device in a.devices.values()]).encode()
        DevCount = 0
        for a in api:
            for key, value in a.devices.items():
                DevCount += 1
        sock.sendto(MESSAGE, (PeerIp, PeerPort))
        tmst = time.strftime('%H:%M:%S')
        if (ThreadRunCount % InfoEveryRunTime) == 0:
            ThreadRunCount = 1
            print('[' + tmst+ '] JSON of ' + str(len(MESSAGE))  +' bytes from ' + str(DevCount) + ' devices sent to ' + PeerIp + ':' + str(PeerPort)) 
                         # Internet      # UDP
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    stopped = threading.Event()
    while not stopped.wait(10):
        update_device_position()
    

    【讨论】:

    • 尝试MESSAGE = json.dumps([dict(device=device, location=device.location()) for a in api for device in a.devices.values()]).encode() 如果device.location() 不是json 可编码的,那么首先将它们转换为可以编码的类型(例如str)。
    • 您是否尝试过简单的 while 循环而不是线程:while not stopped.wait(10): update_device_position() 其中stopped = threading.Event() 是从控制线程传递的。或者你可以use an event loop, to run a function repeatedly
    • 查看 MESSAGE = json.dumps([dict(device=device, location=device.location()) for a in api for a.devices.values()] 结果的更新问题).encode() while not stopped.wait(10) etc etc 与 threading.Timer(10, DevicesPostionUpdate).start() 解决方案相比如何工作,即有什么区别?
    • 阅读我之前评论的最后一句话(替换s/encodable/serializable/)。每次调用Timer() 都会创建一个新线程。 stopped.wait(10) 等到 stopped.set() 被调用或 10 秒过去。
    • 阅读。谢谢。仍然无法弄清楚 json.dumps 的东西... raise TypeError(repr(o) + " is not JSON serializable") TypeError: is not JSON serializable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 2021-11-29
    • 2018-11-09
    • 2014-07-13
    • 1970-01-01
    • 2017-02-23
    • 2018-07-18
    相关资源
    最近更新 更多