बढ़िया, यह काम करता है और यह वास्तव में सरल
class AstGraphGenerator(object):
def __init__(self):
self.graph = defaultdict(lambda: [])
def __str__(self):
return str(self.graph)
def visit(self, node):
"""Visit a node."""
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
def generic_visit(self, node):
"""Called if no explicit visitor function exists for a node."""
for _, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, ast.AST):
self.visit(item)
elif isinstance(value, ast.AST):
self.graph[type(node)].append(type(value))
self.visit(value)
तो यह एक सामान्य NodeVisitor के रूप में ही है, लेकिन मैं एक defaultdict जहां मैं एक बेटे के लिए नोड के प्रकार जोड़ने की है। फिर मैं इस शब्दकोश को pygraphviz.AGraph में पास करता हूं और मुझे अपना अच्छा परिणाम मिलता है।
एकमात्र समस्या यह है कि प्रकार बहुत कुछ नहीं कहता है, लेकिन दूसरी तरफ ast.dump() का उपयोग करना भी वर्बोज़ है।
प्रत्येक नोड के लिए वास्तविक स्रोत कोड प्राप्त करना सबसे अच्छा बात है, क्या यह संभव है?
संपादित करें: अब यह बेहतर है, मैं कन्स्ट्रक्टर में स्रोत कोड भी पास करता हूं और यदि संभव हो तो मैं कोड लाइन प्राप्त करने का प्रयास करता हूं, अन्यथा बस प्रकार को प्रिंट करें।
class AstGraphGenerator(object):
def __init__(self, source):
self.graph = defaultdict(lambda: [])
self.source = source # lines of the source code
def __str__(self):
return str(self.graph)
def _getid(self, node):
try:
lineno = node.lineno - 1
return "%s: %s" % (type(node), self.source[lineno].strip())
except AttributeError:
return type(node)
def visit(self, node):
"""Visit a node."""
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
def generic_visit(self, node):
"""Called if no explicit visitor function exists for a node."""
for _, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, ast.AST):
self.visit(item)
elif isinstance(value, ast.AST):
node_source = self._getid(node)
value_source = self._getid(value)
self.graph[node_source].append(value_source)
# self.graph[type(node)].append(type(value))
self.visit(value)
हाँ, आप कर रहे हैं सही एक बहुत ही सरल कार्यान्वयन है, मैं पहले सोचा था कि मैं सभी संभव मामलों की जांच करने के लिए किया था कि, लेकिन वास्तव में पता चल सके कि यह एक सूची है पहले से ही काफी पेड़ के माध्यम से चलने के लिए है या नहीं .. धन्यवाद बहुत –