Nested arguments not compiling
我正试图将我的代码编译成一个python 3模块。当我在空闲状态下选择"运行模块"时,它运行良好,但当我尝试创建分发时,它会收到以下语法错误:
1 2 3 4 | File"/usr/local/lib/python3.2/dist-packages/simpletriple.py", line 9 def add(self, (sub, pred, obj)): ^ SyntaxError: invalid syntax |
有人能帮忙指出语法有什么问题吗?以下是完整的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import csv class SimpleGraph: def __init__(self): self._spo = {} self._pos = {} self._osp = {} def add(self, (sub, pred, obj)): """ Adds a triple to the graph. """ self._addToIndex(self._spo, sub, pred, obj) self._addToIndex(self._pos, pred, obj, sub) self._addToIndex(self._osp, obj, sub, pred) def _addToIndex(self, index, a, b, c): """ Adds a triple to a specified index. """ if a not in index: index[a] = {b:set([c])} else: if b not in index[a]: index[a][b] = set([c]) else: index[a][b].add(c) def remove(self, (sub, pred, obj)): """ Remove a triple pattern from the graph. """ triples = list(self.triples((sub, pred, obj))) for (delSub, delPred, delObj) in triples: self._removeFromIndex(self._spo, delSub, delPred, delObj) self._removeFromIndex(self._pos, delPred, delObj, delSub) self._removeFromIndex(self._osp, delObj, delSub, delPred) def _removeFromIndex(self, index, a, b, c): """ Removes a triple from an index and clears up empty indermediate structures. """ try: bs = index[a] cset = bs[b] cset.remove(c) if len(cset) == 0: del bs[b] if len(bs) == 0: del index[a] # KeyErrors occur if a term was missing, which means that it wasn't a valid delete: except KeyError: pass def triples(self, (sub, pred, obj)): """ Generator over the triple store. Returns triples that match the given triple pattern. """ # check which terms are present in order to use the correct index: try: if sub != None: if pred != None: # sub pred obj if obj != None: if obj in self._spo[sub][pred]: yield (sub, pred, obj) # sub pred None else: for retObj in self._spo[sub][pred]: yield (sub, pred, retObj) else: # sub None obj if obj != None: for retPred in self._osp[obj][sub]: yield (sub, retPred, obj) # sub None None else: for retPred, objSet in self._spo[sub].items(): for retObj in objSet: yield (sub, retPred, retObj) else: if pred != None: # None pred obj if obj != None: for retSub in self._pos[pred][obj]: yield (retSub, pred, obj) # None pred None else: for retObj, subSet in self._pos[pred].items(): for retSub in subSet: yield (retSub, pred, retObj) else: # None None obj if obj != None: for retSub, predSet in self._osp[obj].items(): for retPred in predSet: yield (retSub, retPred, obj) # None None None else: for retSub, predSet in self._spo.items(): for retPred, objSet in predSet.items(): for retObj in objSet: yield (retSub, retPred, retObj) # KeyErrors occur if a query term wasn't in the index, so we yield nothing: except KeyError: pass def value(self, sub=None, pred=None, obj=None): for retSub, retPred, retObj in self.triples((sub, pred, obj)): if sub is None: return retSub if pred is None: return retPred if obj is None: return retObj break return None def load(self, filename): f = open(filename,"rb") reader = csv.reader(f) for sub, pred, obj in reader: sub = unicode(sub,"UTF-8") pred = unicode(pred,"UTF-8") obj = unicode(obj,"UTF-8") self.add((sub, pred, obj)) f.close() def save(self, filename): f = open(filename,"wb") writer = csv.writer(f) for sub, pred, obj in self.triples((None, None, None)): writer.writerow([sub.encode("UTF-8"), pred.encode("UTF-8"), obj.encode("UTF-8")]) f.close() if __name__ =="__main__": g = SimpleGraph() g.add(("blade_runner","name","Blade Runner")) g.add(("blade_runner","name","Blade Runner")) g.add(("blade_runner","release_date","June 25, 1982")) g.add(("blade_runner","directed_by","Ridley Scott")) print list(g.triples((None, None, None))) print list(g.triples(("blade_runner", None, None))) print list(g.triples(("blade_runner","name", None))) print list(g.triples(("blade_runner","name","Blade Runner"))) print list(g.triples(("blade_runner", None,"Blade Runner"))) print list(g.triples((None,"name","Blade Runner"))) print list(g.triples((None, None,"Blade Runner"))) print list(g.triples(("foo","name","Blade Runner"))) print list(g.triples(("blade_runner","foo","Blade Runner"))) print list(g.triples(("blade_runner","name","foo"))) |
PEP 3113解释了为什么这个特性"tuple参数解包"在python 3中被删除。它还解释了如何移植使用它们的代码。在这种情况下,您需要更改如下函数:
1 2 3 4 | def add(self, (sub, pred, obj)): self._addToIndex(self._spo, sub, pred, obj) self._addToIndex(self._pos, pred, obj, sub) self._addToIndex(self._osp, obj, sub, pred) |
到将元组作为单个参数传递并手动解包的版本:
1 2 3 4 5 | def add(self, sub_pred_obj): sub, pred, obj = sub_pred_obj self._addToIndex(self._spo, sub, pred, obj) self._addToIndex(self._pos, pred, obj, sub) self._addToIndex(self._osp, obj, sub, pred) |
对于
1 | lambda (x, y): (y, x) |
……
1 | lambda xy: (xy[1], xy[0]) |
对于复杂的函数,这可能会变得很难看,但对于复杂的函数,您可能无论如何都希望使用
值得注意的是,通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $ echo 'lambda (x,y): (y,x)' | 2to3 - --- <stdin> (original) +++ <stdin> (refactored) @@ -1 +1 @@ -lambda (x,y): (y,x) +lambda x_y: (x_y[1],x_y[0]) $ echo -e 'def foo((x,y)): return (y,x) ' | 2to3 - --- <stdin> (original) +++ <stdin> (refactored) @@ -1 +1 @@ -def foo((x,y)): +def foo(xxx_todo_changeme): + (x,y) = xxx_todo_changeme |
如果您试图将python 2.x代码移植到3.x(或双版本代码),但不了解这两种语言,那么您几乎肯定希望使用这些工具中的一种,或者使用一个封装它们的IDE插件来提供帮助。(尽管您可能不想按原样使用其输出。)