अलग-अलग चर का शब्दकोश बनाने का सरल तरीका?


220

मैं एक स्ट्रिंग के रूप में एक चर का नाम प्राप्त करने में सक्षम होना चाहता हूं, लेकिन मुझे नहीं पता कि क्या पायथन में इतनी आत्मनिरीक्षण क्षमता है। कुछ इस तरह:

>>> print(my_var.__name__)
'my_var'

मैं ऐसा करना चाहता हूं क्योंकि मेरे पास चर का एक गुच्छा है जिसे मैं एक शब्दकोश में बदलना चाहता हूं जैसे:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

लेकिन मुझे इससे कुछ अधिक स्वचालित चाहिए।

अजगर locals()और है vars(), तो मुझे लगता है कि वहाँ एक रास्ता है।


31
चूंकि लोग इस बात को लेकर असमंजस में दिखते हैं कि मुझसे क्या मांगा गया है, इसलिए मैं इसे यहीं विश्राम दूंगा क्योंकि यह एक दिलचस्प सवाल है। एक सरणी [foo, bar, baz] को देखते हुए आप {'foo': foo, 'bar': bar, 'baz': baz} जैसे शब्दकोश चाहते हैं और आपको पता नहीं है कि सरणी में कौन से चर हैं। इसलिए प्रश्नकर्ता पूछ रहा है कि आपको अजगर में एक स्ट्रिंग के रूप में एक चर का नाम कैसे मिलता है। अब उम्मीद है कि लोग कुछ स्थानों को खोजने के लिए भयानक प्रतिक्रियाओं के माध्यम से नेविगेट कर सकते हैं जहां आप सीखते हैं कि यह वास्तव में अजगर में एक अच्छा विचार क्यों नहीं है।
जेसी शेरलाक

3
संभावित डुप्लिकेट: stackoverflow.com/questions/544919/…
एंडरसन ग्रीन

2
तकनीक का एक उपयोग स्ट्रिंग फॉर्मेटिंग कॉल को सुव्यवस्थित करने के लिए होगा: '{var} {foo} {bar}'। स्वरूप (** नाम (var, foo, बार)), जहां "नामित" वह फ़ंक्शन है जो तानाशाह को लौटाता है ( 'var': var) जैसा कि वर्णित है।
गॉर्डन बीन

4
मुझे लगता है कि यह वास्तव में एक बुरा सवाल है क्योंकि नाम वस्तुओं के लिए मैप किए जाते हैं, आपके पास एक ही ऑब्जेक्ट की ओर इशारा करते हुए कई नाम हो सकते हैं, और मैंने कभी भी उस मैपिंग को निष्क्रिय करने के लक्ष्य को पूरा करने की कोई आवश्यकता नहीं देखी है। तो यह तथ्य कि गलत उत्तर को यहाँ स्वीकार किया जाता है, अर्थहीन है - यदि कोई Google खोज आपको यहाँ लाया है, तो आप स्पष्ट रूप से गलत प्रश्न पूछ रहे हैं।
हारून हॉल

1
यह डिबगिंग के लिए एक महान विचार है!
जॉन ktejik

जवाबों:


48

क्या आप ऐसा करने की कोशिश कर रहे हैं?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

उदाहरण

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

1
Rlotun इसके प्रारंभिक "आत्मा" के करीब है क्योंकि यह नाम की खोज करने की अनुमति देता है। मैं आपके दोनों anwser का उपयोग कर सकता हूं। या शायद टाइप करने के लिए मेरे लानत हाथ का उपयोग करें। कुछ चीजें सिर्फ इसलिए नहीं बनती हैं कि स्वचालित हो ...
ई-सिटिस

7
@ ई-सिटिस: @ राल्टून के काम करने के लिए, आपको चर की सूची प्रदान करनी होगी। यदि आपके पास चर की सूची है, तो उनके नामों की "खोज" करने का क्या मतलब है?
S.Lott

4
स्थानीय और ग्लोबल्स का उपयोग करने के बजाय स्पष्ट रूप से क्यों?

1
@ रॉजर पटे: क्योंकि मैं यह पता नहीं लगा सका कि पूरी कवायद का क्या मतलब था।
S.Lott

242
यह उत्तर पूछे गए प्रश्न का उत्तर नहीं देता है। यदि आपके पास चर की सूची है, तो उनके नामों की "खोज" करने का क्या मतलब है? दोहराव से बचने के लिए ताकि print('x: ' + x)एक के बजाय एक magic_print(x)ही आउटपुट लिखा जा सके और दो बार वेरिएबल का नाम लिखे बिना ही आउटपुट हो सके ।
पायोत्र डोब्रोगोस्ट

130

जैसा कि कहा गया है, यह वास्तव में कुछ ऐसा नहीं है जिसे आप पायथन में करते हैं - चर वास्तव में वस्तुओं के नाम मैपिंग हैं।

हालाँकि , यहाँ एक तरीका यह है कि प्रयास करें और करें:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

14
इस विचार में योग्यता है, लेकिन ध्यान दें कि यदि दो चर नाम समान मान (उदाहरण True) का संदर्भ देते हैं , तो एक अनपेक्षित चर नाम वापस आ सकता है।
अनटुब

14
id(v) == id(a)इसके बजाय क्यों v is a? यह कई चर, जैसे कि स्याही, तार और किसी भी समान रूप से कार्यान्वित उपयोगकर्ता-परिभाषित प्रकार से जुड़ी वस्तुओं के लिए विफल हो जाएगा।

हां, v is aबेहतर विकल्प होगा। और हाँ, निश्चित रूप से खतरनाक सभी संभावित नुकसान दिए गए हैं जो उत्पन्न हो सकते हैं! ;-)
राल्टुन

16
@ ई-सतीस मुझे आश्चर्य है कि आपने इस उत्तर को उत्तर के रूप में चिह्नित नहीं किया है क्योंकि मैं आपकी टिप्पणी से सहमत हूं कि आरलूटन इसके बारे में प्रारंभिक "भावना" के करीब है क्योंकि यह नाम की खोज करने की अनुमति देता है । इसके अतिरिक्त S.Lott का जवाब सब पर अपने सवाल aswer नहीं है ...
पिओर Dobrogost

2
"ओवरकिल और खतरनाक" ... और eval का उपयोग नहीं है?
बग

63

मैं यह काफी कुछ करना चाहता था। यह हैक rlotun के सुझाव के समान है, लेकिन यह एक लाइनर है, जो मेरे लिए महत्वपूर्ण है:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

अजगर 3+

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

3
@keflavich मुझे यह दृष्टिकोण बहुत पसंद आया और समय-समय पर इसका इस्तेमाल किया है। हालांकि मैं इसे कार्यों के अंदर काम करने के लिए नहीं कर सकता। मुझे लगता है कि इसे करने के लिए "बेहतर" तरीके हैं, लेकिन कोई भी उतना अच्छा नहीं है जितना कि nbubis इसे डालता है। क्या आप इसे फ़ंक्शंस केफ्लेविच में उपयोग करने में सक्षम हैं? यह वह जगह है जहां मैं इस बारे में एक सवाल पूछता हूं।
सिंह

10
ध्यान दें कि पायथन 3 में, iteritems()प्रतिस्थापित किया गया हैitems()
जोनाथन व्हीलर

यह अविश्वसनीय है: spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)आउटपुटspam
andreasdr

1
@andreasdr कि वजह से है spam = 1, blah = 1; assert spam is blah। आदिम डेटा प्रकारों की तुलना करते समय समाधान टूट जाता है।
JYun

17

यह एक हैक है। यह सभी पायथन कार्यान्वयन वितरण पर काम नहीं करेगा (विशेष रूप से, जिनके पास नहीं है traceback.extract_stack।)

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

ध्यान दें कि यह हैक नाजुक है:

make_dict(bar,
          foo)

(कॉलिंग मेक_डिक्ट ऑन 2 लाइन्स) काम नहीं करेगा।

मानों से बाहर उत्पन्न करने की कोशिश करने के बजाय fooऔर bar, यह स्ट्रिंग के नामों 'foo' और नामों से बाहर ताना उत्पन्न करने के लिए बहुत अधिक पायथोनिक होगा 'bar':

dict([(name,locals()[name]) for name in ('foo','bar')])

1
स्मार्ट हैक के लिए +1। बेशक, ट्रेस बैक बहुत धीमा है इसलिए इसका उपयोग करने के लिए सुस्त हो सकता है।
ई-सतीस

1
+1111111 !!!! हाँ यह धीमी है, लेकिन जब print("a_very_long_name: {}'.format(a_very_long_name))कौन परवाह करता है की जगह का उपयोग कर !
1

14

यह पायथन में संभव नहीं है, जिसमें वास्तव में "चर" नहीं है। पायथन के नाम हैं, और एक ही वस्तु के लिए एक से अधिक नाम हो सकते हैं।


हाँ, मुझे पता है, मैंने प्रश्न को सरल बना दिया था, लेकिन मुझे "get_var_tags (var) [0]" जैसे कुछ और की उम्मीद थी।
ई-सतीस

10

मुझे लगता है कि मेरी समस्या यह बताने में मदद करेगी कि यह प्रश्न क्यों उपयोगी है, और इसका जवाब देने के तरीके में थोड़ा और अंतर्दृष्टि दे सकता है। मैंने अपने कोड में विभिन्न चर पर त्वरित इनलाइन हेड चेक करने के लिए एक छोटा सा कार्य लिखा। असल में, यह चर नाम, डेटा प्रकार, आकार और अन्य विशेषताओं को सूचीबद्ध करता है, इसलिए मैं अपने द्वारा की गई किसी भी गलती को जल्दी से पकड़ सकता हूं। कोड सरल है:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

इसलिए यदि आपके पास कुछ जटिल डिक्शनरी / लिस्ट / टपल स्थिति है, तो इंटरप्रेटर को आपके द्वारा दिए गए वेरिएबल नाम को वापस करने में काफी मदद मिलेगी। उदाहरण के लिए, यहाँ एक अजीब शब्दकोष है:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

मुझे यकीन नहीं है कि अगर मैंने इसे सही जगह पर रखा, लेकिन मुझे लगा कि इससे मदद मिल सकती है। मुझे आशा है कि यह करता है।


तो अपने सिर की जांच के साथ, क्या यह इस तथ्य के लिए जिम्मेदार है कि चर / नाम कोड में अलग-अलग समय पर अलग-अलग चीजों की ओर इशारा कर सकते हैं? उदाहरण के लिए myconnectionएक बिंदु पर एक बूलियन मान की ओर इशारा किया जा सकता है, दूसरे समय में एक पूर्णांक, और कोड निष्पादन में दूसरे बिंदु पर एक सॉकेट कनेक्शन ??

9

मैंने इस प्रश्न के उत्तर के आधार पर एक छोटा सा उपयोगी कार्य लिखा। मैं इसे यहाँ डाल रहा हूँ अगर यह उपयोगी है।

def what(obj, callingLocals=locals()):
    """
    quick function to print name of input and value. 
    If not for the default-Valued callingLocals, the function would always
    get the name as "obj", which is not what I want.    
    """
    for k, v in list(callingLocals.items()):
         if v is obj:
            name = k
    print(name, "=", obj)

उपयोग:

>> a = 4
>> what(a)
a = 4
>>|

6

मुझे लगता है कि यदि आपके पास पहले से ही मूल्यों की एक विशिष्ट सूची है, तो @ एस द्वारा वर्णित तरीका। लॉट सबसे अच्छा है; हालाँकि, नीचे दिया गया तरीका सभी चर और वर्गों को कोड में जोड़े जाने के लिए अच्छी तरह से काम करता है, चर नाम प्रदान करने की आवश्यकता के बिना यद्यपि आप चाहें तो उन्हें निर्दिष्ट कर सकते हैं। कोड कक्षाओं को बाहर करने के लिए बढ़ाया जा सकता है।

import types
import math  # mainly showing that you could import what you will before d

# Everything after this counts
d = dict(globals())

def kv_test(k,v):
    return (k not in d and 
            k not in ['d','args'] and
            type(v) is not types.FunctionType)

def magic_print(*args):
    if len(args) == 0: 
        return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
    else:
        return {k:v for k,v in magic_print().iteritems() if k in args}

if __name__ == '__main__':
    foo = 1
    bar = 2
    baz = 3
    print magic_print()
    print magic_print('foo')
    print magic_print('foo','bar')

आउटपुट:

{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}

6

अजगर 3 में यह आसान है

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

यह प्रिंट होगा:

myVariable 5


यह रालोटुन के दृष्टिकोण के समान है लेकिन थोड़ा सा सरल है
आधिकारिक तौर

10
-1। एक नई दुभाषिया खिड़की खोलें और कोशिश करें for v in locals()
वायु

मुझे पूरी तरह से यकीन नहीं है कि आपका क्या मतलब है?
आधिकारिक

4
यह एक त्रुटि देगा: रनटाइमइरर: पुनरावृति के दौरान शब्दकोश का आकार बदल गया ...
निजाम बी।

2
हालाँकि आप कर सकते हैंfor v in list(locals()):
Phylliida

5

Python3। कॉलिंग लोकल नेमस्पेस को पकड़ने के लिए निरीक्षण का उपयोग करें, फिर यहां प्रस्तुत विचारों का उपयोग करें। जैसा कि बताया गया है एक से अधिक उत्तर दे सकते हैं।

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

अच्छा जवाब है, लेकिन मेरे लिए यह बेहतर है: ... आईडी (नाम (नाम, कोई नहीं, फ़्रेम .f_back.f_locals)) == ...
इमैनुएल

5

यहां वह फ़ंक्शन है जिसे मैंने चर नामों को पढ़ने के लिए बनाया है। यह अधिक सामान्य है और विभिन्न अनुप्रयोगों में उपयोग किया जा सकता है:

def get_variable_name(*variable):
    '''gets string of variable name
    inputs
        variable (str)
    returns
        string
    '''
    if len(variable) != 1:
        raise Exception('len of variables inputed must be 1')
    try:
        return [k for k, v in locals().items() if v is variable[0]][0]
    except:
        return [k for k, v in globals().items() if v is variable[0]][0]

निर्दिष्ट प्रश्न में इसका उपयोग करने के लिए:

>>> foo = False
>>> bar = True
>>> my_dict = {get_variable_name(foo):foo, 
               get_variable_name(bar):bar}
>>> my_dict
{'bar': True, 'foo': False}

4

धागे को पढ़ने में, मैंने एक बहुत अधिक घर्षण देखा। बुरा जवाब देना काफी आसान है, फिर किसी को सही जवाब देना चाहिए। वैसे भी, यहाँ जो मैंने पाया है।

प्रेषक: [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )

नाम थोड़े अलग हैं - वे वास्तव में वस्तु के गुण नहीं हैं, और वस्तु खुद नहीं जानती कि इसे क्या कहा जाता है।

किसी भी वस्तु का कोई भी नाम या कोई भी नाम नहीं हो सकता है।

नाम नेमस्पेस (जैसे एक मॉड्यूल नेमस्पेस, एक उदाहरण नेमस्पेस, एक फ़ंक्शन का स्थानीय नाम स्थान) में रहते हैं।

ध्यान दें: यह कहता है कि वस्तु को स्वयं नहीं पता है कि उसे क्या कहा जाता है , इसलिए वह सुराग था। पायथन ऑब्जेक्ट्स स्व-संदर्भ नहीं हैं। फिर यह कहता है, नाम नामस्थान में रहते हैं । टीसीएल / टीके में हमारे पास यह है। तो शायद मेरा जवाब मदद करेगा (लेकिन इसने मेरी मदद की)

    जज = 123
    प्रिंट eval ("'" + str (id (jj)) + "" ")
    प्रिंट दिर ()

166707048
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']

इसलिए सूची के अंत में 'jj' है।

कोड को फिर से लिखें:

    जज = 123
    प्रिंट eval ("'" + str (id (jj)) + "" ")
    dir में x के लिए ():
        प्रिंट आईडी (eval (x))

161922920
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'jj']
3077447796
136515736
3077408320
3077656800
136515736
161922920

कोड आईडी का यह गंदा सा परिवर्तनशील / वस्तु / जो कुछ भी आप-पांडित्य-कॉल का नाम है।

तो, वहाँ यह है। 'Jj' का मेमोरी एड्रेस वैसा ही होता है जब हम इसे सीधे खोजते हैं, जैसे हम करते हैं डिक्शनरी को ग्लोबल नेम स्पेस में देखते हैं। मुझे यकीन है कि आप ऐसा करने के लिए एक समारोह बना सकते हैं। बस याद रखें कि आपका वैरिएबल / ऑब्जेक्ट / वाइप्स किस नेमस्पेस में है।

QED।


6
आप यहाँ eval के दो पागल उपयोग हैं। पहले बिल्कुल के रूप में एक ही है: print id(jj)। दूसरा बस नाम दिखता है, और अधिक आसानी से किया जा सकता है vars()
नेड बाचेल्डर

2

शायद मैं इस पर काबू पा रहा हूँ ..

str_l = next((k for k,v in locals().items() if id(l) == id(v)))


>>> bar = True
>>> foo = False
>>> my_dict=dict(bar=bar, foo=foo)
>>> next((k for k,v in locals().items() if id(bar) == id(v)))
'bar'
>>> next((k for k,v in locals().items() if id(foo) == id(v)))
'foo'
>>> next((k for k,v in locals().items() if id(my_dict) == id(v)))
'my_dict'

महान! यह वही है जिसे मैं देख रहा था। धन्यवाद @ rh0dium ... \ Nvariable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
Majdi

2
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

2

मैंने पीपल का घोल अपलोड किया । यह C # के nameofफ़ंक्शन के बराबर परिभाषित करने वाला एक मॉड्यूल है ।

यह उस फ़्रेम के लिए बायटेकोड निर्देशों के माध्यम से पुनरावृत्त करता है, जिसे इसके अंदर बुलाया गया है, चर / विशेषताओं के नाम प्राप्त करना। नाम में पाए जाते हैं .argreprके LOADसमारोह के नाम निम्न निर्देश।


2

मैंने इस तरह के जादू को जोरदार तरीके से करने के लिए पैकेज टोना लिखा । तुम लिख सकते हो:

from sorcery import dict_of

my_dict = dict_of(foo, bar)

1

अधिकांश वस्तुओं में __name__ विशेषता नहीं होती है । (कक्षाएं, फ़ंक्शंस, और मॉड्यूल करते हैं? किसी भी अधिक प्रकार के बिलिन प्रकार जो एक होते हैं?)

आप के लिए और क्या उम्मीद करेंगे print(my_var.__name__)के अलावा अन्य print("my_var")? क्या आप सीधे स्ट्रिंग का उपयोग कर सकते हैं?

आप "स्लाइस" एक तानाशाही कर सकते हैं:

def dict_slice(D, keys, default=None):
  return dict((k, D.get(k, default)) for k in keys)

print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})

वैकल्पिक रूप से:

throw = object()  # sentinel
def dict_slice(D, keys, default=throw):
  def get(k):
    v = D.get(k, throw)
    if v is not throw:
      return v
    if default is throw:
      raise KeyError(k)
    return default
  return dict((k, get(k)) for k in keys)

2
+1 लेकिन मुझे पता है कि नाम मौजूद नहीं है, हर कोई इसे "लिटिरल" जैसा कुछ क्यों लेता है? आपका समाधान समस्या को हल नहीं करता है क्योंकि मैं नाम को नुकसान नहीं पहुंचाना चाहता हूं, मैं पहले से ही प्रश्न में दिए गए तानाशाह समाधान करूंगा।
ई-सतीस

3
@ ई-सिटिस: यदि स्थानीय लोगों में सब कुछ का उपयोग कर () आपकी समस्या का हल करता है, तो मुझे पता नहीं है कि आप क्या पूछ रहे हैं। मुझे लगता है कि आप कॉल करने के साथ ठीक हैं some_func(var), इसलिए मैंने इंगित करने का प्रयास किया है कि बहुत दूर से नहीं है some_func("var"), साथ ही आप एक साथ कई चर के लिए नाम-मूल्य मैपिंग प्राप्त करने की अनुमति दे सकते हैं।

1

खैर, मुझे कुछ दिन पहले उसी जरूरत का सामना करना पड़ा और मुझे एक चर का नाम प्राप्त करना पड़ा जो कि वस्तु की ओर इशारा कर रहा था ।

और यह इतना आवश्यक क्यों था?

संक्षेप में मैं माया के लिए प्लग-इन बना रहा था । कोर प्लग-इन C ++ का उपयोग करके बनाया गया था, लेकिन GUI पायथन के माध्यम से तैयार किया गया है (जैसा कि इसके प्रोसेसर गहन नहीं)। चूंकि मैं, अभी तक, returnडिफ़ॉल्ट को छोड़कर प्लग-इन से कई मानों को नहीं जानता हूं MStatus, इसलिए पायथन में एक शब्दकोश को अपडेट करने के लिए मुझे चर का नाम पास करना था, जो जीयूआई को लागू करने वाली वस्तु की ओर इशारा करता है और जो शब्दकोश को केवल प्लग-इन में समाहित करता है और फिर MGlobal::executePythonCommand()शब्दकोश को माया के वैश्विक दायरे से अद्यतन करने के लिए उपयोग करता है ।

यह करने के लिए कि मैंने क्या किया है:

import time

class foo(bar):

    def __init__(self):
        super(foo, self).__init__()
        self.time = time.time() #almost guaranteed to be unique on a single computer

    def name(self):
        g = globals()
        for x in g:
            if isinstance(g[x], type(self)):
                if g[x].time == self.time:
                    return x
                    #or you could:
                    #return filter(None,[x if g[x].time == self.time else None for x in g if isinstance(g[x], type(self))])
                    #and return all keys pointing to object itself

मुझे पता है कि यह सही नहीं है globalsकई कुंजी में एक ही वस्तु की ओर इशारा किया जा सकता है जैसे:

a = foo()
b = a
b.name()
>>>b
or
>>>a

और वह तरीका थ्रेड-सेफ नहीं है। अगर मैं ग़लत हूं तो मेरी गलती सुझाएं।

कम से कम इस दृष्टिकोण ने वैश्विक दायरे में किसी भी चर का नाम प्राप्त करके मेरी समस्या को हल कर दिया जो ऑब्जेक्ट को स्वयं इंगित करता है और इसे प्लग-इन पर तर्क के रूप में पास करता है, क्योंकि यह आंतरिक रूप से उपयोग करता है।

मैंने इस पर int(आदिम पूर्णांक वर्ग) की कोशिश की, लेकिन समस्या यह है कि इन आदिम वर्गों को दरकिनार नहीं किया जाता है (कृपया इसके गलत इस्तेमाल किए गए तकनीकी शब्दावली को सही करें)। आप फिर से लागू कर सकते हैं intऔर कर सकते हैं, int = fooलेकिन आदिम की a = 3वस्तु कभी नहीं होगी foo। जिसे दूर करने के लिए आपको काम a = foo(3)पर निकलना a.name()होगा।


1

अजगर 2.7 और नए के साथ भी शब्दकोश समझ है जो इसे थोड़ा छोटा करता है। यदि संभव हो तो मैं शीर्ष उत्तर की तरह eval (eval is बुराई) के बजाय getattr का उपयोग करूंगा। स्वयं कोई भी वस्तु हो सकती है, जिसका संदर्भ आपकी ओर देखना है। यह एक वस्तु या स्थानीय हो सकता है = स्थानीय () आदि।

{name: getattr(self, name) for name in ['some', 'vars', 'here]}

1

मैं इसी तरह की समस्या पर काम कर रहा था। @ S.Lott ने कहा "यदि आपके पास चर की सूची है, तो उनके नामों की" खोज "करने का क्या मतलब है?" और मेरा जवाब सिर्फ यह देखना है कि क्या यह किया जा सकता है और यदि किसी कारण से आप अपने चर को सूची में टाइप करना चाहते हैं। तो वैसे भी, मेरे शोध में मैं इस धागे के पार आया था और मेरा समाधान थोड़ा विस्तारित है और @rlotun समाधान पर आधारित है। एक अन्य बात, @unutbu ने कहा, "इस विचार में योग्यता है, लेकिन ध्यान दें कि यदि दो चर नाम एक ही मूल्य (उदाहरण के लिए सत्य) का संदर्भ देते हैं, तो एक अनपेक्षित चर नाम वापस आ सकता है।" इस अभ्यास में यह सच था इसलिए मैंने प्रत्येक संभावना के लिए इसके समान एक सूची समझ का उपयोग करके इससे निपटा isClass = [i for i in isClass if i != 'item']:। इसके बिना "आइटम" प्रत्येक सूची में दिखाई देगा।

__metaclass__ = type

from types import *

class Class_1: pass
class Class_2: pass
list_1 = [1, 2, 3]
list_2 = ['dog', 'cat', 'bird']
tuple_1 = ('one', 'two', 'three')
tuple_2 = (1000, 2000, 3000)
dict_1 = {'one': 1, 'two': 2, 'three': 3}
dict_2 = {'dog': 'collie', 'cat': 'calico', 'bird': 'robin'}
x = 23
y = 29
pie = 3.14159
eee = 2.71828
house = 'single story'
cabin = 'cozy'

isClass = []; isList = []; isTuple = []; isDict = []; isInt = []; isFloat = []; isString = []; other = []

mixedDataTypes = [Class_1, list_1, tuple_1, dict_1, x, pie, house, Class_2, list_2, tuple_2, dict_2, y, eee, cabin]

print '\nMIXED_DATA_TYPES total count:', len(mixedDataTypes)

for item in mixedDataTypes:
    try:
        # if isinstance(item, ClassType): # use this for old class types (before 3.0)
        if isinstance(item, type):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isClass.append(mapping_as_str)
            isClass = [i for i in isClass if i != 'item']

        elif isinstance(item, ListType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isList.append(mapping_as_str)
            isList = [i for i in isList if i != 'item']

        elif isinstance(item, TupleType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isTuple.append(mapping_as_str)
            isTuple = [i for i in isTuple if i != 'item']

        elif isinstance(item, DictType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isDict.append(mapping_as_str)
            isDict = [i for i in isDict if i != 'item']

        elif isinstance(item, IntType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isInt.append(mapping_as_str)
            isInt = [i for i in isInt if i != 'item']

        elif isinstance(item, FloatType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isFloat.append(mapping_as_str)
            isFloat = [i for i in isFloat if i != 'item']

        elif isinstance(item, StringType):
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    isString.append(mapping_as_str)
            isString = [i for i in isString if i != 'item']

        else:
            for k, v in list(locals().iteritems()):
                if v is item:
                    mapping_as_str = k
                    other.append(mapping_as_str)
            other = [i for i in other if i != 'item']

    except (TypeError, AttributeError), e:
        print e

print '\n isClass:', len(isClass), isClass
print '  isList:', len(isList), isList
print ' isTuple:', len(isTuple), isTuple
print '  isDict:', len(isDict), isDict
print '   isInt:', len(isInt), isInt
print ' isFloat:', len(isFloat), isFloat
print 'isString:', len(isString), isString
print '   other:', len(other), other

# my output and the output I wanted
'''
MIXED_DATA_TYPES total count: 14

 isClass: 2 ['Class_1', 'Class_2']
  isList: 2 ['list_1', 'list_2']
 isTuple: 2 ['tuple_1', 'tuple_2']
  isDict: 2 ['dict_1', 'dict_2']
   isInt: 2 ['x', 'y']
 isFloat: 2 ['pie', 'eee']
isString: 2 ['house', 'cabin']
   other: 0 []
'''

इस मुद्दे को मैं इसके साथ ले जाऊँगा कि नाम वस्तुओं के गुण नहीं हैं। किसी एकल ऑब्जेक्ट में कई नाम हो सकते हैं, या कोई भी नाम नहीं हो सकता है। उदाहरण के लिए, आपने pi = pieअपने कोड में जोड़ा है, आपको अपनी isFloatसूची में एक अतिरिक्त प्रविष्टि मिलेगी । यदि आपने tuple_1[0]अपनी mixedDataTypesसूची में जोड़ा है , तो दो बार "एक" आपके कोड में होने के बावजूद कोई नाम नहीं मिलेगा (हालांकि स्ट्रिंग इंटर्निंग के लिए धन्यवाद, वे दोनों एक ही वस्तु के संदर्भ होंगे)।
ब्लेककनथ

1
@ बाल्कन --- मैं सहमत हूँ। यह केवल कुछ ऐसा करने का एक और तरीका है जो वास्तव में करने के लिए नहीं था। मैंने यह नहीं कहा कि यह अद्वितीय परिणाम प्रस्तुत करता है या यह अचूक है। ऐसा करने में मुझे पता चला कि प्रयोग piऔर eचर के रूप में अवांछित उत्पादन हुआ और ऐसा इसलिए है क्योंकि दोनों ही mathपुस्तकालय का हिस्सा हैं । मेरे लिए यह सिर्फ यह देखने के लिए एक अभ्यास था कि क्या यह किया जा सकता है भले ही अंतिम परिणाम सही नहीं है। किताबों से गुजरती इस भाषा की मेरी सीख में अब तक केवल यही है। मेरी राय में, यदि आप वास्तव में भाषा सीखना चाहते हैं तो आपको "क्या अगर" खेलना होगा और देखना होगा कि आप क्या करते हैं।
माइकल स्वार्टज

1

आप आसानी से उपयोग कर सकते हैं

>>> from easydict import EasyDict as edict
>>> d = edict({'foo':3, 'bar':{'x':1, 'y':2}})
>>> d.foo
3
>>> d.bar.x
1
>>> d = edict(foo=3)
>>> d.foo
3

एक और उदाहरण:

>>> d = EasyDict(log=False)
>>> d.debug = True
>>> d.items()
[('debug', True), ('log', False)]

1

Python3 पर, इस फ़ंक्शन को स्टैक में बाहरी सबसे अधिक नाम मिलेगा:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

यह कोड पर कहीं भी उपयोगी है। पहले मैच की तलाश में उलटे हुए ढेर को ट्रेस करता है।


0

हालांकि यह शायद एक भयानक विचार है, यह राल्टुन के उत्तर के समान ही है, लेकिन यह सही परिणाम को अधिक बार लौटाएगा।

import inspect
def getVarName(getvar):
  frame = inspect.currentframe()
  callerLocals = frame.f_back.f_locals
  for k, v in list(callerLocals.items()):
    if v is getvar():
      callerLocals.pop(k)
      try:
        getvar()
        callerLocals[k] = v
      except NameError:
        callerLocals[k] = v
        del frame
        return k
  del frame

आप इसे इस तरह कहते हैं:

bar = True
foo = False
bean = False
fooName = getVarName(lambda: foo)
print(fooName) # prints "foo"

0

सूची मिलनी चाहिए फिर लौटेंगे

def get_var_name(**kwargs):
    """get variable name
        get_var_name(var = var)
    Returns:
        [str] -- var name
    """
    return list(kwargs.keys())[0]

0

यह चर का नाम नहीं लौटाएगा लेकिन आप आसानी से वैश्विक चर से शब्दकोश बना सकते हैं।

class CustomDict(dict):
    def __add__(self, other):
        return CustomDict({**self, **other})

class GlobalBase(type):
    def __getattr__(cls, key):
        return CustomDict({key: globals()[key]})

    def __getitem__(cls, keys):
        return CustomDict({key: globals()[key] for key in keys})

class G(metaclass=GlobalBase):
    pass

x, y, z = 0, 1, 2

print('method 1:', G['x', 'y', 'z']) # Outcome: method 1: {'x': 0, 'y': 1, 'z': 2}
print('method 2:', G.x + G.y + G.z) # Outcome: method 2: {'x': 0, 'y': 1, 'z': 2}

0

साथ python-varnameआप आसानी से यह कर सकते हैं:

pip install python-varname

from varname import Wrapper

foo = Wrapper(True)
bar = Wrapper(False)

your_dict = {val.name: val.value for val in (foo, bar)}

print(your_dict)

# {'foo': True, 'bar': False}

डिस्क्लेमर: मैं उस अजगर-वर्नेम लाइब्रेरी का लेखक हूं।


-1
>>> a = 1
>>> b = 1
>>> id(a)
34120408
>>> id(b)
34120408
>>> a is b
True
>>> id(a) == id(b)
True

इस तरह शायद 'a' या 'b' के लिए varname मिलता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.