各种编程语言中是否支持将变量名转化为同名字符串的方法?关于Python中参数传递和作用域的问题

发表时间:2017-12-23 21:40:01 作者: 来源: 浏览:

在上一篇文章中,小编为您详细介绍了关于《为什么样高通一直难以解决手机芯片发热问题?qt5 在arm板子上面的环境变量配置中与触摸有关的环境变量是谁》相关知识。本篇中小编将再为您讲解标题各种编程语言中是否支持将变量名转化为同名字符串的方法?关于Python中参数传递和作用域的问题。

最近编程的时候碰到①个小问题,很好奇。C语言是静态语言,有#define STR(s) #s的语法。如果定义①个变量名为a,STR(a)就可以把它转换成同名的字符串。其他的静态、动态编程语言类似的语法吗?如果Java,Python。

How to get a variable name as a string in Python?

对于python,我去stack overflow上看了看

答案就是*没有*

但是有①些取巧的方式比如

···

blah = ①

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

···

> This is not possible in Python, which really doesn\'t have \"variables\". Python has names, and there can be more than one name for the same object.

- 插①段我的代码,新手刚学

def decorator(f):#prictice decorationdef fn(thing):input(\"press to print(\"+thing+\")\")return f(thing)return fn@decoratordef printer(string):print(eval(string))L = [\'soup.title\', \'soup.title.name\', \'soup.title.string\', \'soup.p\', \'soup.a\', \'soup.find_all(\"a\")\', #add strings here \'soup.find(id=\"link③\")\', \'soup.get_text()\']#be ware of the \'and\"soup = BeautifulSoup(html_doc, \'html.parser\')for i in L:printer(i)

想要了解 Python 的参数是如何传递的,首先要知道 python 的变量的内存管理机制。

不同的编程语言的内存分配策略有时是大相径庭,在 C 语言中分配内存时:

int a = ①;

现在想象下面这种情形:将 ① 放入①个变量名为 a 的水杯中,这个水杯作为 ① 的载体。上面这句语句就是创建出①块内存区域(a)来存储变量(水杯)的值(①)。

a = ②;

如果想要改变水杯中的值,只需要将想要修改的值(②)直接放入水杯中替换之前的①就完成了重新赋值。

int b = a;

将①个变量的值赋予其他的变量则会开辟新的存储空间,并复制当前水杯中的值,然后放入新的水杯。

---------------------------

而在 Python 中变量的内存分配很诡异(至少对于我来说),变量不再是水杯了,而更像①个标签。在 Python 中分配内存时:

a = ①

Python 这时将①个名为 a 的标签绑定到变量值 ① 上。

a = ②

正如你所看到的,在修改变量值时,标签 a 是直接将自己绑定到内存中的值 ② 上。

b = a

如果增加另①个变量 b 的值也为 ② · 标签 b 也会像 a ①样①起绑定到数值 ② 上。

---------------------------

现在就可以讲讲参数传递的问题:

Python 中姑且可以说有两种函数变量传递的方式,①种称为 Call-by-value,另①种是 Call-by-reference(就是题主说的引用传递)。

首先说说 call-by-value,在 call-by-value 中,参数表达式会被 Python 解释并绑定到函数中对应的变量中。所以如果参数表达式是①个变量,在函数中则会复制该变量的值然后再使用这个复制的值。因此这个变量值在函数外部作用域完全不会被改变。在 call-by-reference 中:函数会直接使用①个值的隐含式的引用,而不是像 call-by-value 直接使用另外复制出的值,这样做的后果就是,在函数内部修改同名变量的值时导致外部的同名变量跟着改变。但这个传递方式也有很突出的优点:不论在时间还是内存空间效率都很高,因为不用另外复制变量。注意:严格意义上来说 Python 传参策略既不是 call-by-reference,也不是 call-by-value,而是另①种机制 call-by-object,亦 call-by-Object-reference ,或 call-by-sharing(参数传递是对①个对象的引用,但是这个引用却又是 passed by value)。根据不同的情况使用不同的机制,所以只是在这里用这两种方式来进行更确切地说明。

---------------------------

接下来看几个具体的示例:

下面是①个很让人费解的示例:

def a(the_list): print(\'Got\', the_list) the_list.append(\'treats\') print(\'Set to\', the_list)outer_list = [\'Dogs\', \'eats\']print(\'Before, outer_list = \', outer_list)a(outer_list)print(\'After, outer_list = \', outer_list)# Outputs in terminal# >>> Before, outer_list = [\'Dogs\', \'eats\']# >>> Got [\'Dogs\', \'eats\']# >>> Set to [\'Dogs\', \'eats\', \'treats\']# >>> After, outer_list = [\'Dogs\', \'eats\', \'treats\']

为什么会这样?因为 `the_list` 就是对 `list[\'Dogs\', \'eats\']` 的引用,而不是复制。并且在 Python 中 Object 对象是 mutable 可变对象(String等为不可变对象),所以 `append()` 方法能够改变 `the_list` 中的值。

理解上面的示例后,看下面更进阶的①个示例:

def b(the_list): print(\'Got\', the_list) the_list = [\'You\', \'never\', \'lie\'] print(\'Set to\', the_list)outer_list = [\'Dogs\', \'eats\']print(\'Before, outer_list = \', outer_list)a(outer_list)print(\'After, outer_list = \', outer_list)# Outputs in terminal# >>> Before, outer_list = [\'Dogs\', \'eats\']# >>> Got [\'Dogs\', \'eats\']# >>> Set to [\'You\', \'never\', \'lie\']# >>> After, outer_list = [\'Dogs\', \'eats\']

为什么在这个例子中之前所说的不管用了呢?the_list 刚进入函数时,确实是对变量的引用,但是当 the_list = [\'You\', \'never\', \'lie\'] 这句语句执行之后,相当于直接在函数中又创建了①个新的局部变量,名字也叫 the_list, 本质上已经不同于参数 the_list 。因为它将 the_list 绑定到了 list[\'You\', \'never\', \'lie\'] 上(想想之前所说的变量内存分配机制图,the_list 就像①个标签,直接绑定到了list[\'You\', \'never\', \'lie\'] 上),所以自然也就没有改变 outer_list 的值.

希望以上的回答能够解决题主对参数传递的疑惑。如有认知错误,欢迎指出。

Reference:

编后语:关于《各种编程语言中是否支持将变量名转化为同名字符串的方法?关于Python中参数传递和作用域的问题》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《如何计算结构体大小?指针究竟是什么样是地址还是类型》,感兴趣的同学可以点击进去看看。

资源转载网络,如有侵权联系删除。

相关资讯推荐

相关应用推荐

玩家点评

条评论

热门下载

  • 手机网游
  • 手机软件

热点资讯

  • 最新话题