python局部变量和全局变量的问题

shell33168 2017-11-23 07:44:11
为什么在函数里面修改list,list前后都改变了;但是在函数里面修改变量,在函数外面却无法修改呢?

def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4]);
print "函数内取值: ", mylist
return
#
# # 调用changeme函数
mylist = [10,20,30];
changeme( mylist );
print "函数外取值: ", mylist
#


def sum( total ):
#返回2个参数的和."
total = 30 # total在这里是局部变量.
print "函数内是局部变量 : ", total
# return total;
return
total=0
sum(total)
#调用sum函数
print "函数外是全局变量 : ", total



结果:
函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]
函数内是局部变量 : 30
函数外是全局变量 : 0
...全文
408 5 打赏 收藏 举报
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
混沌鳄鱼 2017-11-24
我来说两句: 通常大家所说的函数调用时的传值和传引用都是借用C语言或其它一些静态语言的概念。 因为在C语言中变量就是实际在内存某地址空间上存储值。 函数调用时的实参传值即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。 传引用则是传了实参变量指针(内存地址) 然而Python是完全不同于C语言的实现机制。Python中的变量和C语言中的变量是很不同的。 在Python中一切都是对象,并不存在C语言中的所谓的值, 比如 >>> dir(2) 就能看到一大堆属性。

>>> dir(2)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
var = 1234 这个变量 声明和赋值过程实际上是, 先创建1234这个整数对象,然后再把这个对象的引用绑定给var这个字符串。

>>> var = 1234
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'var': 1234}
再看一个例子

>>> a = 257
>>> id(a)
2845238190192
>>> def foo(arg): print(id(arg))

>>> foo(a)
2845238190192
>>> b = [1,2,3]
>>> id(b)
2845238037832
>>> foo(b)
2845238037832
>>> 
从上面例子可以看到, 无论是不可变对象还是可变对象,传参的时候都是传的对象的引用。 所以严格地说: Python的参数传递既不是传值(pass-by-value),也不是传引用(pass-by-reference),而是对象的引用(pass-by-object-reference),即传递的是一个对象的内存地址。
  • 打赏
  • 举报
回复
oyljerry 2017-11-24
python中函数都是传值,只不过对于list参数,mylist是指向列表的引用,所以传递的是引用的值,因而函数内部通过这个值可以修改引用的链表,函数返回后,也是修改的数据 而total是基本数据类型,函数传递的也是它的值,同时它是不可变对象,因而修改它的话,是修改复制后的值,而函数出来后,原来的值不会变
  • 打赏
  • 举报
回复
sprawling 2017-11-23
#!/usr/bin/env python
# -*- coding:utf-8 -*-

def changeme( mylist ):
   "修改传入的列表"
   print id(mylist)
   mylist.append([1,2,3,4]);
   print "函数内取值: ", mylist
   print id(mylist)
   return
#
# # 调用changeme函数
mylist = [10,20,30];
changeme( mylist );
print "函数外取值: ", mylist
#
print id(mylist)
 
 
def sum( total ):
   #返回2个参数的和."
   total = 30 # total在这里是局部变量.
   print "函数内是局部变量 : ", total
   print id(total)
   # return total;
   return
total=0
sum(total)
print id(total)

#调用sum函数
print "函数外是全局变量 : ", total


  • 打赏
  • 举报
回复
sprawling 2017-11-23
第二个function里面,total是参数,
  • 打赏
  • 举报
回复
赵根硕 2017-11-23
这个问题我觉得可以这样理解,因为我们操作列表的时候操作的直接是这个列表的内存地址上的数据,所以不管我们在什么地方来操作一个列表他的值都会变,而对于一个普通的变量如果想像列表这样,那就必须进行全局变量的声明才可以生效。
  • 打赏
  • 举报
回复
相关推荐
发帖
脚本语言
加入

3.7w+

社区成员

JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • ITBOB • 鲍勃
申请成为版主
帖子事件
创建了帖子
2017-11-23 07:44
社区公告

CSDN 脚本语言社区接受专栏投稿(专栏会在顶部创建专属你的栏目),投稿需满足以下要求:

  • 脚本语言技术相关;
  • 文章持续更新,保持活跃;
  • 内容清晰明了,干货为主;
  • 文章排版有序,有条有理。

本社区开通招聘专栏,发布招聘信息请联系版主,发布者需要保证招聘信息真实有效,CSDN 平台和版主不对招聘内容负责!

联系方式:私聊版主、发送邮件、QQ联系等均可: