On Apr 22, 11:52 am, Aaron Brady <castiro...@gmail.com> wrote: > On Apr 22, 12:09 am, Chris Rebert <c...@rebertia.com> wrote: > > > On Tue, Apr 21, 2009 at 5:51 PM, Aaron Brady <castiro...@gmail.com> wrote: > > > Hi all, > > > > I think Python should have a relation class in the standard library. > > > Fat chance. > > > Perhaps I'm not understanding "relation" correctly, but are you not > > aware ofhttp://docs.python.org/library/sqlite3.html? > > > Cheers, > > Chris > > -- > > I have a blog:http://blog.rebertia.com snip > It only supports numbers and strings. snip
My point is that in undirected relations, it's redundant to maintain reciprocal membership. Each participant is a member of the other. 'child.parent.child is child'. It's not a difficult redundancy to maintain, but it isn't true to the concept. Here is another sample: Tree= Relation( ( "parent", "child", "direction" ) ) nodes= [ object( ) for _ in range( 10 ) ] Tree( ( nodes[ 0 ], nodes[ 1 ], "left" ) ) Tree( ( nodes[ 0 ], nodes[ 2 ], "right" ) ) Here is the query (*non-functional)*: recordset= Tree.select( [ "child" ], "parent is nodes[0] and direction=='left'" ) Here's an alternative*: recordset= Tree.select( [ "child" ], lambda record: record.parent is nodes[0] and record.direction=='left' ) I want some more concise ways of retrieving the same data. Those two don't even work as is.* recordset= Tree.select( operator.and_( operator.is_( 'parent', nodes[0] ), operator.eq( 'direction', 'left' ) ) ) This is evaluated too soon. The comparisons need to be 'functools.partial' functions*. recordset= Tree.select( partial( operator.and, partial( operator.is_, 'parent', nodes[0] ), partial( operator.eq, 'direction', 'left' ) ) ) This is close, but the partial functions just compare strings. They would have to be replaced with specialized functions that can recognize designated strings as field names, and replace them with actual fields. Furthermore, it doesn't address the awkwardness of prefix notation, which is required for function calls that aren't native operators. I think the first is the closest. 'ast' makes it particularly convenient, though maybe not trivial, to parse the selection. Where it sees an 'ast.Name' node, it can replace it with an actual field name. Here it is again*: recordset= Tree.select( [ "child" ], "parent is nodes[0] and direction=='left'" ) The only problem is passing variables in to the expression. By the time 'nodes[0]' would get evaluated, it would be too late to know what it is, without dirty frame stackery. 'select' would need the context of its caller, which isn't available. I think some kind of markers would have to replace any identifiers it would use: recordset= Tree.select( [ "child" ], "parent is %var and direction=='left'", nodes[0] ) It's counterintuitive, but it's better than entirely prefix notation. This way the function gets all the actual objects it needs, and can still take shortcuts in its search. I don't really see the argument for only returning a subset of fields, instead of the entire record where matched, although I may not have experience enough to know the downside, such as in the case of large joins. It could be optional, defaulting to 'select *'. recordset= Tree.select( "parent is %var and direction=='left'", nodes[0] ) Since select returns an iterator, it's probably wise to include a 'selectone' function, like the 'Cursor.fetchone' function in 'sqllite3'. Of course, one could just add a '.next()' call to the front of the query. record= next( Tree.select( "parent is %var and direction=='left'", nodes[0] ) ) or record= Tree.selectone( "parent is %var and direction=='left'", nodes[0] ) Does anyone see a better way? Would anyone have use for it? Do you agree that it is more conceptually true to data structures like trees? Is the optimization worth a specialized syntax? Even if selection used a linear-time search, would encapsulating relations be an improvement over redundant and cyclic attributes? Are the equivalents in existing packages just as light-weight and functional? That is, is it competitive? Furthermore, is anyone developing something which uses a quoted expression in a custom evaluation? I'd be interested in seeing those results too. I understand that languages like LISP and Logix ( http://www.livelogix.com/logix/ ) are suited for it, but I want something that is just a single class. Is it outside the scope of Python's capabilities to do? -- http://mail.python.org/mailman/listinfo/python-list