web-gelistirme-sc.com

Bir iade ifadesinden sonra daha fazla iş yapmanın bir yolu var mı?

Sonuç döndürdükten sonra bir fonksiyonda daha fazla çalışabilirsem biraz merak ettim. Temelde, girişleri işledikten sonra piramit çerçevesini (sadece python ile kodlayan) kullanarak bir site yapıyorum, sayfayı oluşturmak için değişkenler döndürüyorum ama bazen sayfayı oluşturduktan sonra daha fazla iş yapmak istiyorum.

Örneğin, siteme geliyorsunuz ve profilinizi güncelliyorsunuz ve tek umursadığınız şey onun başarılı olması, bu yüzden 'başarı!' ama bu yaptıktan sonra, güncellemenizi alıp ne yaptığınızla ilgili faaliyet günlüklerimi güncellemek, arkadaşlarınızın etkinlik akışlarını vb. güncellemek istiyorum. Şu anda değer verdiğiniz sonuç durumunu iade etmeden önce hepsini yapıyorum. Merak ediyorum ki bunu yapabilirsem, kullanıcıların cevaplarını daha hızlı alabilmeleri için.

Daha önce ve en kötü durumda çok işlem yaptım, bu işi yapmak için sadece bir iş parçacığı tutabilirim ancak bir iade ifadesinden sonra iş yapmanın bir yolu olsaydı, bu daha kolay olurdu.

örnek:

def profile_update(inputs):
  #take updates and update the database 
  return "it worked"
  #do maintainence processing now..
22
Lostsoul

Hayır, ne yazık ki, return ifadesine bastığınızda, işlevden/yöntemden dönersiniz (dönüş değeri olsun veya olmasın).

Geri dönüş için dokümanlarından :

return, geçerli işlev çağrısını ifade listesi (veya Yok) ile birlikte dönüş değeri olarak bırakır.

Jeneratör işlevlerine veverimdeyimine bakmak isteyebilirsiniz, bu, işlevden bir değer döndürmenin ve işlemeye devam edildiğinde, işlev çağrıldığında döndürülecek başka bir değer hazırlamanın bir yoludur. bir dahaki sefer.

9
Levon

Neden bir içerik yönetimi kullanmıyorsunuz? Temelde tam olarak ne istersen onu yapar.

İşte Python belgelerinin kanonik örneği.

from contextlib import contextmanager

@contextmanager
def tag(name):
    print "<%s>" % name
    yield
    print "</%s>" % name

Böylece, işleviniz için sadece yapardınız:

@contextmanager
def profile_update(inputs):
  #take updates and update the database 
  yield "it worked"
  #do maintainence processing now..

Ve aramak için, sadece yapardın:

with profile_update(inputs) as result: #pre-yield and yield here
    # do whatever while in scope
# as you move out of scope of with statement, post-yield is executed

EDIT: Sadece bazı şeyleri deniyordum ve sonuçta, bir verim ifadesiyle, fonksiyonun hala sonuna kadar çalıştığı ortaya çıktı. İşte noktası ve işlerin ne zaman gerçekleştirileceğini gösteren aptal bir örnek.

def some_generator(lst):
    for elem in lst:
        yield elem
    lst[0] = "I WAS CHANGED POST-YIELD!!!!"

>>> q = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> gen = some_generator(q)
>>> for e in gen:
...    print e, q

0 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
6 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
7 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
8 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
9 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print q
['I WAS CHANGED POST YIELD!!!', 1, 2, 3, 4, 5, 6, 7, 8, 9]

Bir bağlam yöneticisi, yinelemeyi durdurmak için (ve daha temiz sözdizimi) iki nextçağrısına gerek duymama avantajına sahiptir, ancak birden fazla değer veya başka bir şey döndürmek isterseniz, bu şekilde de yapabilirsiniz, ancak yazının verimini görebilirsiniz. Jeneratör nextçağrısında StopIteration'ı yükseltene kadar aslında çağrılmaz (fors StopIterationolduğunda sona erer)


Herhangi bir sebepten ötürü, @contextmanager tekliflerinden daha yüksek bir kontrol derecesine ihtiyacınız varsa, __enter__ ve __exit__ yöntemleriyle bir sınıf tanımlayabilirsiniz:

class MyContextClass(object):
    # ...

    def __enter__(self):
        # do some preprocessing
        return some_object

    def __exit__(self, exc_type, exc_value, traceback):
        # do some post processing
        # possibly do some processing of exceptions raised within the block
        if exc_type == MyCustomErrorType:
            return True #don't propagate the error
15
Jeff Tratner

Eğer bir try-bloktan dönerseniz geri döndükten sonra yine de bazı işler yapabilirsiniz, nihayet-blok still çalıştırılacak, ör.

def fun():
    try:
        return
    finally:
        print "Yay! I still got executed, even though my function has already returned!"

Alıntı Dokümanlar :

Dönüş bir nihayet Yan tümcesi olan bir try ifadesinin denetiminden geçtiğinde, bu son madde İşlevinden gerçekten ayrılmadan önce yürütülür.

9
Giel

Hayır, bir dönüş değeri arayan kişiye geri verir ve durur.

Arayan (lar) da sizin kontrolünüz altındaysa (piramit çerçevesinin bir parçası değil), profile_updates dosyasını aşağıdaki gibi görünecek şekilde değiştirebilirsiniz:

def profile_update(inputs):
    #take updates and update the database 
    def post_processing_task():
        #do maintainence processing now..
    return ("it worked", post_processing_task)

Ve sonra arayanı sadece bir cevap yerine bir çift (response, task) beklemesini bekleyin. response bölümü ile hemen bir şey yapabilir (kullanıcıya iletir), ardından işlem sonrası işlemesi için task() işlevini çağırın.

Bu, profile_update 'nin daha sonra hangi kodun yürütülmesi gerektiğini belirlemesine izin verir (ve bu detayları gizli tutar ve daha yüksek seviyelerde saklar), ancak daha yüksek seviyenin kullanıcıya bir yanıt iletme akışını belirleme ve daha sonra işlemeyi yürütme akışını belirlemeye izin verir arkaplan.

3
Ben
import threading

def profile_update(inputs):

    # call function to take updates and update the database 
    update_function(inputs)

    # call the maintainence_function here
    t = threading.Thread(target=maintainence_function, args=[input1, input2])
    # setDaemon=False to stop the thread after complete
    t.setDaemon(False)
    # starting the thread
    t.start()

    # return response/anything-else you want to return
    return "it worked"



def update_function(inputs):
    # updating the database process here

def maintainence_function(input1, input2):
    #do maintainence processing now..

Burada python'un diş açma fonksiyonunu kullanıyoruz. 

Öncelikle güncelleme işlevini çağırırız (gerekirse bu işlevi iş parçacığında da kullanabilirsiniz; yanıt bu işleve bağlı değilse ve hemen yanıt vermeniz gerekiyorsa). 

Ardından maintainence_function işlevini tamamlayacak ve bitirdikten sonra duracak bir iplik yarattık. Ancak bu işlev bitene kadar yanıt gecikmeyecektir. 

yani: return "işe yaradı" döndürülür ve daha sonra iş parçacığı, eğer bir bit işlem varsa, işlevi keepence_function işlevinin çalışmasını sürdürür.

1
Shinto Joseph

try-except-finally yapısı ile hile yapmak mümkündür. Örnek:

def function():
  try:
    #do some stuff here
    return x
  except Exception:
    #do something when an error occures
  finally:
    #do here whatever you wanna do after return

Bir istisna yakalanmış olsa bile finally ifadesinin çalıştırılacağını unutmayın.

0
e. Tronics

sanırım aradığınız şey:

def foo (): # bir şeyler denemek: sonunda bir şeyler döndürmek: # dönüş sonra

0
Gianla