अभिकथन: देखें फ़ंक्शन मानचित्रण किसी मौजूदा समापन बिंदु फ़ंक्शन को अधिलेखित कर रहा है: मुख्य


86

क्या किसी को पता है कि मैं एक मौजूदा समापन बिंदु फ़ंक्शन को अधिलेखित नहीं कर सकता अगर मेरे पास इस तरह के दो यूआरएल नियम हैं

app.add_url_rule('/',
                 view_func=Main.as_view('main'),
                 methods=["GET"])

app.add_url_rule('/<page>/',
                 view_func=Main.as_view('main'),
                 methods=["GET"])

वापस ट्रेस करें:

Traceback (most recent call last): 
  File "demo.py", line 20, in <module> methods=["GET"]) 
  File ".../python2.6/site-packages/flask‌​/app.py", 
    line 62, in wrapper_func return f(self, *args, **kwargs) 
  File ".../python2.6/site-packages/flask‌​/app.py", 
    line 984, in add_url_rule 'existing endpoint function: %s' % endpoint)  
AssertionError: View function mapping is overwriting an existing endpoint 
    function: main

क्या आप पूछ रहे हैं कि आप कैसे कर सकते हैं, या आप क्यों कर सकते हैं?
माइकल डेविस

5
यह काम क्यों नहीं करता मैं एक ट्यूटोरियल का अनुसरण कर रहा हूं
किम्मी

1
यदि किसी को यह जानने की उत्सुकता है कि फ्लास्क में अद्वितीय दृश्य नामों की यह सीमा क्यों है, तो एक समान प्रश्न के लिए मेरा उत्तर देखें: stackoverflow.com/a/47558985/4440675 यह उत्तर बताता है कि प्रत्येक विधि के लिए एक अद्वितीय नाम रखने के पीछे क्या तर्क जाता है।
अमित त्रिपाठी

जवाबों:


67

यदि वे समान दृश्य विधि की ओर इशारा कर रहे हैं तो भी आपके दृश्य नामों को अद्वितीय होने की आवश्यकता है।

app.add_url_rule('/',
                 view_func=Main.as_view('main'),
                 methods = ['GET'])

app.add_url_rule('/<page>/',
                 view_func=Main.as_view('page'),
                 methods = ['GET'])

दूसरे शब्दों में, .as_view($VIEW_NAME)विधि कॉल में $ VIEW_NAME को एक अद्वितीय स्ट्रिंग नाम के रूप में पारित किया जाना चाहिए।
देवी

109

यह वही समस्या मेरे साथ हुई जब मेरे पास मॉड्यूल में एक से अधिक एपीआई फ़ंक्शन थे और प्रत्येक फ़ंक्शन को 2 डेकोरेटर्स के साथ लपेटने की कोशिश की:

  1. @ App.route ()
  2. मेरा कस्टम @exception_handler डेकोरेटर

मुझे यह समान अपवाद मिला क्योंकि मैंने उन दो सज्जाकारों के साथ एक से अधिक फ़ंक्शन लपेटने का प्रयास किया:

@app.route("/path1")
@exception_handler
def func1():
    pass

@app.route("/path2")
@exception_handler
def func2():
    pass

विशेष रूप से, यह नाम आवरण के साथ कुछ कार्यों को पंजीकृत करने की कोशिश के कारण होता है :

def exception_handler(func):
  def wrapper(*args, **kwargs):
    try:
        return func(*args, **kwargs)
    except Exception as e:
        error_code = getattr(e, "code", 500)
        logger.exception("Service exception: %s", e)
        r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code})
        return Response(r, status=error_code, mimetype='application/json')
  return wrapper

फ़ंक्शन का नाम बदलने से यह मेरे लिए हल हो गया ( आवरण ।__ name__ = func .__ name__ )।

def exception_handler(func):
  def wrapper(*args, **kwargs):
    try:
        return func(*args, **kwargs)
    except Exception as e:
        error_code = getattr(e, "code", 500)
        logger.exception("Service exception: %s", e)
        r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code})
        return Response(r, status=error_code, mimetype='application/json')
  # Renaming the function name:
  wrapper.__name__ = func.__name__
  return wrapper

फिर, एक से अधिक समापन बिंदु को सजाने का काम किया।


27
आप functools.wrapsफ़ंक्शन का नाम बदलने के लिए भी उपयोग कर सकते हैं ।
ryannjohnson

4
मुझे wrapper.__name__इसके बजाय उपयोग करना था wrapper.func_name। शायद यह python2 और python3 के बीच अंतर है?
अनुनाद

2
डेकोरेटर का उपयोग करके मेरी फ्लास्क रेस्टफुल एपीआई में यही समस्या थी। wrapper.__name__ = func.__name__कॉल करने से पहले रैपर ने समस्या हल की।
टॉम वोजिक

28

@ App.route का उपयोग करने वाले उपयोगकर्ताओं के लिए, कुंजी-तर्क का उपयोग करना बेहतर endpointहोता है, फिर रुई बहू__name__ जैसे मूल्य का जप करना । उसका उदाहरण लेना होगा:

@app.route("/path1", endpoint='func1')
@exception_handler
def func1():
    pass

@app.route("/path2", endpoint='func2')
@exception_handler
def func2():
    pass

8

फ्लास्क के लिए आपको एक 'व्यूपॉइंट फंक्शन' को 'एंडपॉइंट' के साथ जोड़ना होगा। आप Main.as_view('main')दो बार कॉल कर रहे हैं जो दो अलग-अलग फ़ंक्शन बनाता है (मेमोरी कार्यक्षमता में बिल्कुल समान कार्यक्षमता लेकिन अलग है)। लघु कहानी, आपको बस करना चाहिए

main_view_func = Main.as_view('main')

app.add_url_rule('/',
             view_func=main_view_func,
             methods=["GET"])

app.add_url_rule('/<page>/',
             view_func=main_view_func,
             methods=["GET"])

7

मैं इसे और अधिक 'टेम्पलेट' प्रकार के समाधान में जोड़ना चाहूंगा।

def func_name(f):
    def wrap(*args, **kwargs):
        if condition:
            pass
        else:
            whatever you want
        return f(*args, **kwargs)
    wrap.__name__ = f.__name__
    return wrap

बस एक दिलचस्प लेख जोड़ना चाहूंगा "डेमिस्टिफ़ाइंग डेकोरेटर्स" जो मैंने हाल ही में पाया: https://sumit-ghosh.com/articles/demystifying-decorators-python/


4

यह तब भी हो सकता है जब आपके पास विभिन्न मार्गों पर समान फ़ंक्शन नाम हों।


2

यदि आपको लगता है कि आपके पास अद्वितीय समापन बिंदु नाम हैं और फिर भी यह त्रुटि दी गई है, तो शायद आप समस्या का सामना कर रहे हैं । मेरे साथ भी ऐसा ही था।

यह समस्या फ्लास्क 0.10 के साथ है यदि आपके पास एक ही संस्करण है तो इससे छुटकारा पाने के लिए निम्न कार्य करें:

sudo pip uninstall flask
sudo pip install flask=0.9

1

फ्लास्क मुद्दे के लिए एक फिक्स है # 570 हाल ही में शुरू की गई फ्लास्क (फ्लास्क 0.10) जो इस अपवाद को बढ़ाती है।

Https://github.com/mitsuhiko/flask/issues/796 देखें

इसलिए यदि आप फ्लास्क / app.py पर जाते हैं और 4 लाइनों 948..951 पर टिप्पणी करते हैं, तो यह तब तक मदद कर सकता है जब तक कि समस्या नए संस्करण में पूरी तरह से फिर से शुरू न हो जाए।

उस परिवर्तन का स्वरूप यहां है: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1


3
पुन: "जब तक समस्या को एक नए संस्करण में पूरी तरह से हल नहीं किया जाता है": हल होने के लिए कोई "मुद्दा" नहीं है। जैसा कि मुद्दा चर्चा से पता चला है, प्रश्न में कोड के मामले में एक अपवाद का उठाना अपेक्षित परिणाम है। जैसा कि स्वीकृत उत्तर में बताया गया है, समापन बिंदु संघर्ष में हैं। यह फ्लास्क के उपयोगकर्ता के कोड में एक गलती है, फ्लास्क में ही नहीं।
मार्क हिल्ड्रेथ

0

यदि वे एक ही दृश्य विधि की ओर इशारा कर रहे हैं, तो भी आपके दृश्य नामों को विशिष्ट होने की आवश्यकता है, या आप फंक्शनलूल इंपोर्ट रैप के साथ जोड़ सकते हैं और @wraps https://docs.python.org/2/library/functools.html का उपयोग कर सकते हैं


0

फ्लास्क 0.9 का उपयोग करें इसके बजाय निम्नलिखित कमांड का उपयोग करें sudo pip uninstall flask

sudo pip install flask==0.9

0

जोड़ा जा रहा है @wraps(f)रैपर फ़ंक्शन के ऊपर से मेरी समस्या हल हो गई।

def list_ownership(f):
    @wraps(f)
    def decorator(*args,**kwargs):
        return f(args,kwargs)
    return decorator
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.