एक शब्दकोश में अजगर में यदि key byte string है तो json.dumps त्रुटि फेंक देगा, इसलिए मैं उन्हें पास करने से पहले सभी keys को string के रूप में पुनरावर्ती रूप से परिवर्तित करने का प्रयास कर रहा हूं। करने के लिए json.dumps

Note: json.dumps converts the value to str using default function but not keys

निम्नलिखित मेरा कार्य है जो किसी भी byte string keys की जांच करेगा और उन्हें string में बदल देगा:

def keys_string(d):
    rval = {}
    if not isinstance(d, dict):
        if isinstance(d,(tuple,list,set)):
            v = [keys_string(x) for x in d]
            return v
        else:
            return d
    for k,v in d.items():
        if isinstance(k,bytes):
            k = k.decode()
        if isinstance(v,dict):
            v = keys_string(v)
        elif isinstance(v,(tuple,list,set)):
            v = [keys_string(x) for x in v]
        rval[k] = v
    return rval

मैं django में कुछ कोड डिबग कर रहा हूँ

मैं अपने कोड के निश्चित बिंदु पर request ऑब्जेक्ट की जांच करना चाहता हूं

तो मेरे पास है

request_dir = dir(request)

फिर keys_string का उपयोग करके किसी भी बाइट कुंजी को स्ट्रिंग में बदलें (अन्यथा जेसन डंप त्रुटि फेंक देगा)

request_dir_keys_stringed = keys_string(request_dir)

फिर अंत में

json.dumps(request_dir_keys_stringed, indent=4, sort_keys=True, default=str)

जब मैं request_dir_keys_stringed = keys_string(request_dir) करने की कोशिश कर रहा हूं तो यह कहता है

in keys_string
    for k,v in d.items():
RuntimeError: dictionary changed size during iteration

मैंने ऐसा तब पाया जब:

k: user और v: <SimpleLazyObject: <User: test@gmail.com>>

मैंने request.session ऑब्जेक्ट के लिए कोशिश की, यह ऐसी त्रुटि नहीं फेंकता है। लेकिन कुछ वस्तु करते हैं।

request_session_dir = dir(request.session)
request_session_dir_keys_stringed = keys_string(request_session_dir)
json.dumps(request_session_dir_keys_stringed, indent=4, sort_keys=True, default=str)

ऐसे हालात में क्या करें

समस्या को पुन: पेश करने के लिए अधिक जानकारी:

$ python --version
Python 3.7.3

$ django-admin --version
2.2.6

def articles(request):
    request_dir = dir(request)
    request_dir_keys_stringed = keys_string(request_dir)
    print(json.dumps(request_dir_keys_stringed, indent=4, sort_keys=True, default=str)
    return render(request, 'articles/main_page/articles.html')

समाधान लागू करने के बाद key_string बन जाता है:

def keys_string(d):
    rval = {}
    if not isinstance(d, dict):
        if isinstance(d,(tuple,list,set)):
            v = [keys_string(x) for x in d]
            return v
        else:
            return d
    keys = list(d.keys())
    for k in keys:
        v = d[k]
        if isinstance(k,bytes):
            k = k.decode()
        if isinstance(v,dict):
            v = keys_string(v)
        elif isinstance(v,(tuple,list,set)):
            v = [keys_string(x) for x in v]
        rval[k] = v
    return rval


        request_dir = dir(request)
        request_dir_keys_stringed = keys_string(request_dir)
        print(json.dumps(request_dir_keys_stringed, indent=4, sort_keys=True, default=str)

और अब अनुरोध वस्तु बिना किसी त्रुटि के दिखाया गया है

1
Santhosh Yedidi 9 जिंदा 2020, 14:01

1 उत्तर

सबसे बढ़िया उत्तर

request.user SimpleLazyObject है जिसमें एक कॉलबैक है जो एक क्लोजर है जो उसी request ऑब्जेक्ट का संदर्भ रखता है। और फिर वह कॉलबैक request ऑब्जेक्ट को नया attr request._cached_user बनाकर अपडेट करता है यदि वह मौजूद नहीं है। इसलिए request.user को देखने से संभवतः एक नई request._cached_user विशेषता बन जाएगी।

एक विचार इसे कोड अंशों के साथ समझाना आसान है।

Django स्रोत कोड से:

class SimpleLazyObject(LazyObject):
    def __init__(self, func):
        ...

class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.user = SimpleLazyObject(lambda: get_user(request))

def get_user(request):
    if not hasattr(request, '_cached_user'):
        request._cached_user = auth.get_user(request)
    return request._cached_user

इसलिए यदि आप डिक्शनरी कीज़ के माध्यम से अधिक स्थिर चलना चाहते हैं, तो आपको तानाशाही की कॉपी पर पुनरावृति करने की आवश्यकता है:

keys = list(d.keys())
for k in keys:
    v = d[k]
    if isinstance(k, bytes):
        ...
2
petraszd 9 जिंदा 2020, 15:18