Çalışma zamanında dinamik olarak işlevleri çalıştırdığım ve "yerelleştirilmiş" kapsamı takip etmem gereken bir senaryo var. Aşağıdaki örnekte, "startScope" ve "endScope" aslında "yuvalama" seviyelerini oluşturacaktı (gerçekte, bu yerelleştirilmiş kapsamda yer alan öğeler baskı ifadeleri değil ... başka yerlerde ve yuvada veri gönderen işlev çağrılarıdır) orada izlenir startScope/endScope sadece geçerli yuvalama derinliğini başlatmak/sonlandırmak için kullanılan kontrol bayraklarını ayarlar.Python'da dinamik yerelleştirilmiş bir alan oluşturmak mümkün mü?
Bu, iç içe geçmiş verileri izlemek için iyi çalışır, ancak istisnalar başka bir konudur. İdeal olarak, bir istisna mevcut lokalize kapsamın "düşmesi" ile sonuçlanacak ve tüm fonksiyonu sona ermeyecektir (aşağıdaki örnekte benim fonksiyonum).
def startScope():
#Increment our control object's (not included in this example) nesting depth
control.incrementNestingDepth()
def endScope():
#Decrement our control object's (not included in this example) nesting depth
control.decrementNestingDepth()
def myFunction():
print "A"
print "B"
startScope()
print "C"
raise Exception
print "D"
print "This print statement and the previous one won't get printed"
endScope()
print "E"
def main():
try:
myFunction()
except:
print "Error!"
sonrasında bu olur (teorik olarak) çıkışı çalıştırma:
>>> main()
A
B
C
Error!
E
>>>
ben yukarıda yazdım bu mümkün değildir oldukça eminim - Sadece bir resmini boyamak istedi sonuç elde etmeye çalışıyorum tür sonuç.
Python'da böyle bir şey mümkün mü?
Düzenleme: bu aslında nasıl kullanıldığını ait A (uzun olsa) daha alakalı örnek:
class Log(object):
"""
Log class
"""
def __init__(self):
#DataModel is defined elsewhere and contains a bunch of data structures/handles nested data/etc...
self.model = DataModel()
def Warning(self, text):
self.model.put("warning", text)
def ToDo(self, text):
self.model.put("todo", text)
def Info(self, text):
self.model.put("info", text)
def StartAdvanced(self):
self.model.put("startadvanced")
def EndAdvanced(self):
self.model.put("endadvanced")
def AddDataPoint(self, data):
self.model.put("data", data)
def StartTest(self):
self.model.put("starttest")
def EndTest(self):
self.model.put("endtest")
def Error(self, text):
self.model.put("error", text)
#myScript.py
from Logger import Log
def test_alpha():
"""
Crazy contrived example
In this example, there are 2 levels of nesting...everything up to StartAdvanced(),
and after EndAdvanced() is included in the top level...everything between the two is
contained in a separate level.
"""
Log.Warning("Better be careful here!")
Log.AddDataPoint(fancyMath()[0])
data = getSerialData()
if data:
Log.Info("Got data, let's continue with an advanced test...")
Log.StartAdvanced()
#NOTE: If something breaks in one of the following methods, then GOTO (***)
operateOnData(data)
doSomethingCrazy(data)
Log.ToDo("Fill in some more stuff here later...")
Log.AddDataPoint(data)
Log.EndAdvanced()
#(***) Ideally, we would resume here if an exception is raised in the above localized scope
Log.Info("All done! Log some data and wrap everything up!")
Log.AddDataPoint({"data": "blah"})
#Done
#framework.py
import inspect
from Logger import Log
class Framework(object):
def __init__(self):
print "Framework init!"
self.tests = []
def loadTests(self, file):
"""
Simplifying this for the sake of clarity
"""
for test in file:
self.tests.append(test)
def runTests(self):
"""
Simplifying this for the sake of clarity
"""
#test_alpha() as well as any other user tests will be run here
for test in self.tests:
Log.StartTest()
try:
test()
except Exception,e :
Log.Error(str(e))
Log.EndTest()
#End
Bunun hangi yönlerinin zorunlu olduğunu ve hangisinin esnek olduğunu açıklayabilir misiniz? Ayrıca, bu "kapsamlar" ı istisna işleminden başka bir şey üzerinde herhangi bir etkiye sahip olmak için istersiniz/ister misiniz? Eğer istisna “ana” olarak yakalanırsa, “yazdır” “E” yi çalıştırabilmenin hiçbir yolu yoktur; istisna ilerledikçe, yürütmeyi daha düşük bir seviyede "devam ettiremezsiniz". – BrenBarn
Bu örnek için, sadece sonuçla ilgileniyorum. Örnek (yukarıda yazıldığı gibi), daha önce bahsettiğiniz sebepten dolayı işe yaramayacaktır. Esnekliğe gelince - "myFunction" un içeriği üzerinde doğrudan kontrol sahibi değilim ... tek bildiğim "startScope" ve "endScope" olarak adlandırılacak ve bu aramaları uygun gördüğüm şekilde halledebiliyorum. Şu anda, bu, ayrı bir kontrol sınıfında bir yığından ittirmek/atmak anlamına gelir. Bu veriler için çalışır, ancak istisna işleme başka bir hikaye. Umudum, bu tür şeylerle uğraşan bir çeşit ortak tasarım deseni var ... – Novark