2012-07-02 57 views
6

我想做到以下幾點:Python 2.7版使用輸入的功能作爲一個字符串和可變

print "CC =",CC 

但作爲一個函數,這樣我只需要編寫一次變量CC。我不能解決如何在一個函數中做到這一點,因爲它總是評估CC爲浮點數(它是)...有沒有辦法接受函數的輸入作爲字符串和浮點數?

我嘗試這樣做:

def printme(a): 
    b='%s' % a 
    print b 
    return b 

但當然只能打印的a的價值,而不是它的名稱。

+2

Python是動態類型的,所以簡單的答案是「是的,當然!」。長答案取決於你所嘗試過的東西,你能分享你所做的事情,錯誤以及你的期望嗎? –

+0

我已經嘗試了多種東西,這裏是我嘗試打印字符串和浮點數的一個地方,但它導致打印浮點數和沒有字符串: – malby

+0

def printme(a): b ='%s',a 印片b 返回b – malby

回答

0

如果我理解你正確,你想要這樣的東西?

def f(a): 
    print('{0}: = {1}'.format(locals().keys()[0], a)) 

更新:

我知道的例子不使一個很大的意義,因爲它基本相同:

def f(a): 
    print('a: {0}'.format(a)) 

我只是想點OP到當地人(),因爲我不太明白他想要完成什麼。

我想這是更多什麼他尋找:

def f(**kwargs): 
    for k in kwargs.keys(): 
     print('{0}: {1}'.format(k, kwargs[k])) 


f(a=1, b=2) 
+1

這不會起作用,因爲變量不在函數的本地範圍內 – l4mpi

+0

這與編寫'print'a =%s'%a'完全相同,因爲本地名稱將始終爲'a'。如果這真的是OP所需要的,那麼由於Python的工作方式而無法完成。 –

+0

這不起作用,本地名稱將永遠是'a'。 –

0

不正是你想要的,但很容易做到:

def printme(**kwargs): 
    for key, value in kwargs.items(): 
     print '%s=%s' % (key, value) 
    return value 

In [13]: printme(CC=1.23, DD=2.22) 
CC=1.23 
DD=2.22 
Out[13]: 1.23 
1

也許一本字典是一個解決問題的更好的方法。假設你有要使用多個名稱 - 值對,你可以把它們放在一個dict

params = {"CC": 1.2345, "ID": "Yo!", "foo": "bar"} 

然後,例如,你可以打印格式良好的這樣的所有名稱和值:

for key in params: 
    print "{0} = {1}".format(key, params[key]) 

但是,由於它仍然不清楚爲什麼您正在嘗試這樣做,很難說這是否是正確的方法。

+1

之所以這樣,我只需要寫一次CC而不是兩次。我會做很多這樣的速記是有用的,我使用python的應用程序是科學計算,所以編碼數學算法時,你一直在做這個調試,例如在matlab中,這很簡單,因爲你只需輸入變量名並且matlab返回它的值。 – malby

+2

+1這不是OP想要的,但這是OP應該做的。我在SO上看到了很多類似於這個問題的問題,並且他們每個人都最終決定使用字典是解決問題的最方便和最pythonic的方式。 – Vader

+0

@Vader,我看不出有關字符串格式的問題。 OP的問題是如何*獲取*函數內部的變量名和值而不提供* both * explicit(「有沒有一種方法可以接受作爲字符串和浮點數的函數的輸入」和「.. 。所以我只需要寫一次變量CC「)。 – catchmeifyoutry

0

如果我的理解正確,您希望在當前範圍內打印變量名稱及其值?這通常不可能使用而不使用解釋器跟蹤函數或sys._getframe,通常只有在您知道自己在做什麼時才應該使用它。這樣做的原因是,打印功能已經從主叫範圍得到當地人沒有其他辦法:

def a(): 
    x = 1 
    magic_print("x") #will not work without accessing the current frame 

你可以沒有這些做的是明確地傳遞當地人這樣的函數:

def printNameAndValue(varname, values): 
    print("%s=%s" % (varname, values[varname])) 

def a(): 
    x = 1 
    printNameAndValue("x", locals()) #prints 'x=1' 

編輯:

查看catchemifyoutry的解答使用inspect模塊(內部使用sys._getframe)的答案。對於直接完整性使用跟蹤功能的解決方案 - 有用的,如果你使用的Python 2.0和檢查是不可用;)

from sys import settrace 

__v = {} #global dictionary that holds the variables 

def __trace(frame, event, arg): 
    """ a trace function saving the locals on every function call """ 
    global __v 
    if not event == "call": 
     return __trace 
    __v.update(frame.f_back.f_locals) 

def enableTrace(f): 
    """ a wrapper decorator setting and removing the trace """ 
    def _f(*a, **kwa): 
     settrace(__trace) 
     try: 
      f(*a, **kwa) 
     finally: 
      settrace(None) 
    return _f 

def printv(vname): 
    """ the function doing the printing """ 
    global __v 
    print "%s=%s" % (vname, __v[vname]) 

保存在一個模塊中,並使用這樣的:

from modulenamehere import enableTrace, printv 

@enableTrace 
def somefunction(): 
    x = 1 
    [...] 
    printv("x") 
+0

mmm,感謝您付出的努力,我認爲您是正確的,因爲沒有解決方案,現在看來我的原始解決方案是最好的解決方案,由於python將所有輸入作爲默認值進行壓縮,實際上是一個難題禁用此方法? – malby

+0

不知道「壓制所有輸入」的意思,但通過@catchmeifyoutry查看使用inspect(內部使用跟蹤功能)的解決方案的答案。 – l4mpi

0

使用一個全局變量來實現這一目標,func.__globals__.keys()包含傳遞給func的所有變量,所以我過濾掉挑動與__,並將它們存儲在列表中的名稱。 與func()的每次調用func.__globals__.keys()得到更新與新的變量名稱,所以比較新的varn與舊的glo結果剛剛添加的新變量。

glo=[] 
def func(x): 
    global glo 
    varn=[x for x in func.__globals__.keys() if not x.startswith('__') and x!=func.__name__] 
    new=list(set(varn)^set(glo)) 
    print("{0}={1}".format(new[0],x)) 
    glo=varn[:] 

輸出:

>>> a=10 
>>> func(a) 
a=10 
>>> b=20 
>>> func(20) 
b=20 
>>> foo='cat' 
>>> func(foo) 
foo=cat 
>>> bar=1000 
>>> func(bar) 
bar=1000 
3

您可以使用inspect模塊(見this SO question):

def printme(x): 
    import inspect 
    f = inspect.currentframe() 
    val = f.f_back.f_locals[x] 
    print x, '=', val 


CC = 234.234  
printme('CC') # <- write variable name only once 
# prints: CC = 234.234 
1

我覺得這是你所需要的解決方案:

def printme(x): 
    keys_list = [key for key, value in globals().iteritems() if value == x] 
    print keys_list 
    for key in keys_list: 
     if id(globals()[key]) == id(x): 
      result = "%s = %s" %(key, x) 
      print result 
      break 

    return result 

例如如果聲明一個變量:

>>> c=55.6 

然後導致printme(c)中的

>>> 'c = 55.6' 

注意:此方法是基於全局唯一ID匹配。

+0

這隻適用於變量在'globals'中,這意味着它對函數本地沒有用處...... – l4mpi

+0

@ l4mpi根據被問到的問題,一個變量將被傳遞給一個函數。這意味着,該變量將不在該函數的locals()中,而在globals()中。所以我首先檢查了globals()。這不可能是確切的解決方案,但我認爲它可以通過少許修改來提供所需的解決方案,即首先檢查本地()。 –

+0

這是錯誤的,並且表明您對可變範圍的理解不足。如果在模塊級聲明變量(或明確聲明爲全局變量),變量將只在'globals'中。如果變量是在另一個函數內部聲明的,它將既不在'globals'也不在你的打印函數的'locals'內 - 嘗試'def f(x):printme(x)',然後調用'f(1)'。請參閱catchmeifyoutrys對使用調用作用域的本地實際解決方案的答案。 – l4mpi

相關問題