यह किसी भी माध्यम से किसी भी कोड के लिए अनुशंसित नहीं है, लेकिन नीचे की तरह एक बदसूरत हैक किया जा सकता है। मैं इस किया था अजगर एएसटी एपीआई की बेहतर समझ है करने के लिए है, तो किसी को जो वास्तविक दुनिया कोड में इस का उपयोग करता है इससे पहले कि यह :-)
#!/usr/bin/python
# -*- coding: utf-8-unix -*-
#
# AST hack to replace symbol reference in instance methods,
# so it will be resolved as a reference to class variables.
#
import inspect, types, ast
def trim(src):
lines = src.split("\n")
start = lines[0].lstrip()
n = lines[0].index(start)
src = "\n".join([line[n:] for line in lines])
return src
#
# Method decorator that replaces symbol reference in a method
# so it will use symbols in belonging class instead of the one
# in global namespace.
#
def nsinclude(*args):
# usecase: @nsinclude()
# use classname in calling frame as a fallback
stack = inspect.stack()
opts = [stack[1][3]]
def wrap(func):
if func.func_name == "tempfunc":
return func
def invoke(*args, **kw):
base = eval(opts[0])
src = trim(inspect.getsource(func))
basenode = ast.parse(src)
class hackfunc(ast.NodeTransformer):
def visit_Name(self, node):
try:
# if base class (set in @nsinclude) can resolve
# given name, modify AST node to use that instead
val = getattr(base, node.id)
newnode = ast.parse("%s.%s" % (opts[0], node.id))
newnode = next(ast.iter_child_nodes(newnode))
newnode = next(ast.iter_child_nodes(newnode))
ast.copy_location(newnode, node)
return ast.fix_missing_locations(newnode)
except:
return node
class hackcode(ast.NodeVisitor):
def visit_FunctionDef(self, node):
if func.func_name != "tempfunc":
node.name = "tempfunc"
hackfunc().visit(node)
hackcode().visit(basenode)
newmod = compile(basenode, '<ast>', 'exec')
eval(newmod)
newfunc = eval("tempfunc")
newfunc(*args, **kw)
return invoke
# usecase: @nsinclude
if args and isinstance(args[0], types.FunctionType):
return wrap(args[0])
# usecase: @nsinclude("someclass")
if args and args[0]:
opts[0] = args[0]
return wrap
class Bar:
FOO = 987
BAR = 876
class Foo:
FOO = 123
BAR = 234
# import from belonging class
@nsinclude
def dump1(self, *args):
print("dump1: FOO = " + str(FOO))
# import from specified class (Bar)
@nsinclude("Bar")
def dump2(self, *args):
print("dump2: BAR = " + str(BAR))
Foo().dump1()
Foo().dump2()
स्रोत
2011-07-12 13:47:24
ठीक है, यह बहुत बुरा है। मुझे याद है कि आप ऐसा कुछ कर सकते थे जो मैं जावा में करने की कोशिश कर रहा था? मुझे यकीन नहीं है। – Theodor
मुझे पूरा यकीन है कि आप जावा में जो कुछ भी पूछते हैं वह कर सकते हैं! – Iacks
और मुझे पूरा यकीन है कि आप जावा में अन्य 9 0% चीजें नहीं कर सकते हैं जिन्हें आप करना चाहते हैं। प्रयास और प्रतिबिंब हैकिंग के लिए – aaronasterling