Python变量

4.10 Python变量

4.10.1 变量介绍

变量,顾名思义,就是可以变化的量。变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。
Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
在 Python中,变量就是变量,它没有类型,我们所说的类型是变量所指的内存中对象的类型。如果有个数据不被任何变量所指向,则会被Python的回收机制回收掉,以节省内存。
在Python中,一切皆对象。所以其实:变量就是对象的名字!

4.10.2 变量名

变量在程序中需要用变量名进行表示,在Python中,变量的命名是需要满足一定的条件的:

  1. 允许包括英文(中文等其他国家文字也可以)、数字以及下划线_,不能以数字开头
  2. 名称区分大小写,例如:fun和Fun是不同的变量名。
  3. 不要使用关键字作为变量名,这可能会导致未知的错误。
    以下是一些变量命名的建议:
  4. 以_开头的变量是有特殊意义的,最好不要创建以_开头的变量名。
  5. 变量命名建议采用驼峰命名法(MyName、UserId)或蛇形命名法(my_name、user_id)。
  6. 特殊变量或者常量建议全部大写。
  7. 类名建议使用驼峰命名法。
  8. 变量名最好要做到见名知意。

4.10.3 变量的赋值

赋值运算符=用来给变量赋值。=左边是一个变量名,=右边是存储在变量中的值。
>>> counter = 100 # 整型变量
>>> miles = 1000.0 # 浮点型变量
>>> name = "atom" # 字符串
>>> a = b = c = 1 # 链式赋值
>>> a, b, c = 1, 2, 3 # 多个变量同时复制
>>> a, *b, c = 1, 2, 3, 4, 5 # 装包
>>> a, b = b, a # 交换变量
>>> a, b, c = [1, 2, 3] # 解包赋值
>>> x += 1 # 增强赋值
在Python中,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,这点和其它编程语言有所不同。因此,Python是一种动态语言,而与之对应的静态语言在变量赋值时需要先定义变量类型,如果后续赋值时类型和定义时不匹配,就会报错。
和静态语言相比,动态语言更加灵活。
让我们来看看在Python中变量赋值时发生了什么。当我们将atom赋值给name时:
>>> name = 'atom'
Python解释器会先在内存中创建一个atom的字符串,然后再创建一个名为name的变量,并指向atom
我们可以想象有个箱子,里面装了一个数据,就是字符串的atom,而变量就像是一个标签,标签名是name,贴在了刚才的箱子上。如果是贴在装有100数字类型的箱子上,那么这个变量就是100。
在Python中,一定要牢记一点:变量无类型,数据才有类型。变量就是个标签,贴在什么数据上,就是什么数据类型。下面这个例子能很好的说明这一点:

a = 100
b = a
a = 'string'
print(f'a: {a}')
print(f'b: {b}')

a: string
b: 100

4.10.3.2 Python中表示常量

所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:
>>> PI = 3.14
但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法。

4.10.3.3 浅复制、深复制

前面我们讲过可以通过id()函数获取某个对象的id,这个id对于每个数据都是不同的。如果两个变量的id一样,那么则说明这两个变量指向同一个对象。

a = 'str'
b = [1, 2, 3]
c = {1: [22, 33]}
aa = a
bb = b
cc = c
print(id(a) == id(aa))
print(id(b) == id(bb))
print(id(c) == id(cc))
print(id(c[1]) == id(cc[1]))

True
True
True
True

像上面,通过=进行复制的一般称为浅复制(比如:aa = a),浅复制后,aa和a这两个变量其实指向的都是同一个数据。所以具有一样的id。只要修改了原始数据后,所有通过浅复制指向这个数据的变量的值都会发生变化:

b = [1, 2, 3]
bb = b
b.pop()
print(f'b: {b}')
print(f'bb: {bb}')

b: [1, 2]
bb: [1, 2]

我们可以通过导入copy模块中的deepcopy函数来进行深复制。对于不可变数据,比如:元组或字符串等,深复制后指向的还是同一个数据。与浅复制没有区别。但是对于可变数据,比如:列表和字典,深复制后,虽然变量的值还是一样,但是指向的数据已经不是同一个了。如下:

from copy import deepcopy
a = 'str'
b = [1, 2, 3]
c = {1: [22, 33]}
aaa = deepcopy(a)
bbb = deepcopy(b)
ccc = deepcopy(c)
print(id(a) == id(aaa))
print(id(b) == id(bbb))
print(id(c) == id(ccc))
print(id(c[1]) == id(ccc[1]))

True
False
False
False

深复制后,由于指向的不是相同的数据,于是,修改其中一个变量后,并不会影响到其它变量。如下:

from copy import deepcopy

b = [1, 2, 3]
bb = deepcopy(b)
print(id(b) == id(bb))
b.pop()
print(f'b: {b}')
print(f'bb: {bb}')

False
b: [1, 2]
bb: [1, 2, 3]

4.10.4 变量的作用域

根据变量的作用范围,可以将变量分为:局部变量和全局变量。

4.10.4.1 局部变量

在函数、类、方法等内部定义的变量,它的作用域也仅限于其定义时的内部,在外部则不能使用,我们将这样的变量称为局部变量(Local Variable)。
当函数或类被执行时,Python 会为其分配一块临时的存储空间,所有在函数、类中定义的变量,都会存储在这块空间中。而在函数、类执行完毕后,这块临时存储空间随即会被释放并回收,该空间中存储的变量自然也就无法再被使用。

def add(a, b):
    c = 10
    print(c)
    print(a+b)


add(1, 2)
print(c)

10
3
Traceback (most recent call last):
File "E:\studypy\tmp.py", line 6, in
print(c)
NameError: name 'c' is not defined

如上,在add函数中定义了一个变量c,并赋值为10,调用add函数时是可以正常打印出来c的。但是在函数外面打印则报错:name 'c' is not defined
正常情况下,在定义的内部结构体中可以获取和使用局部变量,也可以对局部变量进行修改和删除。
如果想要在外部使用内部变量,则需要在变量前面加上关键字global进行声明。声明该变量是一个全局变量。

def add(a, b):
    global c
    c = 10
    print(c)
    print(a + b)


add(1, 2)
print(c)

10
3
10

4.10.4.1.1 locals()函数

通过locals()函数,我们可以得到一个包含当前作用域内所有变量的字典。这里所谓的“当前作用域”指的是,在函数内部调用 locals() 函数,会获得包含所有局部变量的字典;而在全局范围内调用 locals() 函数,其功能和 globals() 函数相同。
注意:
1、locals() 函数返回的字典中,会默认包含有很多变量,这些都是 Python 主程序内置的,我们暂时不用理会它们。
2、我们无法可以通过修改上面获得的字典来修改局部变量的值。

def myprint():
    name = 'zhangsan'
    print(locals()['name'])
    locals()['name'] = "lisi"
    print(name)


myprint()

zhangsan
zhangsan

4.10.4.1.2 vars(object)函数

vars()函数也是 Python 内置函数,其功能是返回一个指定 object 对象(对于函数不起作用)范围内所有变量组成的字典。如果不传入object 参数,vars() 和 locals() 的作用完全相同。

name = "Python"
class Demo:
    name = "Python 教程"
print(vars(Demo))
print(vars())

{'module': 'main', 'name': 'Python 教程', 'dict': <attribute 'dict' of 'Demo' objects>, 'weakref': <attribute 'weakref' of 'Demo' objects>, 'doc': None}
{'name': 'main', 'doc': None, 'package': None, 'loader': <_frozen_importlib_external.SourceFileLoader object at 0x0000017DD89A7C40>, 'spec': None, 'annotations': {}, 'builtins': <module 'builtins' (built-in)>, 'file': 'E:\studypy\tmp3.py', 'cached': None, 'name': 'Python', 'Demo': <class 'main.Demo'>}

4.10.4.2 全局变量

在模块内定义的变量称为全局变量(Global Variable),和局部变量不同,全局变量的默认作用域是整个程序,即全局变量可以在所有函数、类、类方法中直接使用。

c = 5
def add(a, b):
    print(f'c: {c}')
    print(f'a+b={a + b}')
add(1, 2)

c: 5
a+b=3

globals() 函数为 Python 的内置函数,它可以返回一个包含全局范围内所有变量的字典,该字典中的每个键值对,键为变量名,值为该变量的值。
注意,globals() 函数返回的字典中,会默认包含有很多变量,这些都是 Python 主程序内置的,我们暂时不用理会它们。
可以看到,通过调用 globals() 函数,我们可以得到一个包含所有全局变量的字典。并且,通过该字典,我们还可以访问指定变量,甚至如果需要,还可以修改它的值。

name = 'zhangsan'
print(globals()['name'])
globals()['name'] = "lisi"
print(name)

zhangsan
lisi

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python变量 - Python技术站

(0)
上一篇 2023年4月2日
下一篇 2023年4月2日

相关文章

  • 文档字符串

    5.5 文档字符串 开发者在编写函数或模块时不光要自己能看懂,在和他人合作共同开发或者被他人调用时也需要他人也能看懂。这个时候就可以为自己编写的函数、模块或者类添加相应的文档字符串(docstring)进行说明了。一般的,如果想要在模块中添加模块文档字符串,则需要在模块的最上方用3个双引号引住内容,这部分内容则自动会被识别为模块的文档字符串。注意:模块文档字…

    Python开发 2023年3月31日
    00
  • 类属性和对象属性

    6.3 类属性和对象属性 在类定义中,属性按照归属分为对象属性、类属性。按照调用的私密性分为一般属性和私有属性。 6.3.1 类属性和对象属性 对象属性是最常用到的一种属性。即使我们对上面的类:MyClass1实例化了一个mc的对象,mc对象也不能进行有实质的操作。因为mc对象的类:MyClass1中既没有定义属性也没有定义方法。在定义类时还能定义类属性。接…

    Python开发 2023年3月31日
    00
  • Python关键字(保留字)

    3.2 Python关键字(保留字) 保留字又称关键字,不可用于普通标识符。关键字的拼写必须与这里列出的完全一致。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字。>>> import keyword>>> keyword.kwlist [‘False’, ‘None’, ‘True’,…

    Python开发 2023年4月2日
    00
  • AI修复照片

    一、前言 最近闲来无事,翻了翻以前的老照片,看着多年前的老照片,感慨万千,仿佛又回到了以前的青春岁月。只可惜青春易逝,无法重来。意气风发,头角峥嵘的画面只能永远地留存在相片之中了。只叹当时没有多拍几张照片留作纪念,可惜当时设备也不好,照片效果不佳。留下遗憾。最近学习了Python,发现可以通过Python使用AI来修复老旧照片,而且修复后的效果非常不错。AI…

    2023年4月2日
    00
  • 定义(创建)、调用函数及返回值

    5.2 定义(创建)、调用函数及返回值 5.2.1 定义(创建)函数 要调用一个函数,首先要定义它。在Python中使用关键字def来定义一个函数。函数通常由函数名、参数列表以及一系列语句组成的函数体构成的。函数定义的一般格式如下: def 函数名(参数列表): 函数体 例如: def sayhello(): print(‘hello’) 最简单的函数: d…

    Python开发 2023年4月2日
    00
  • 面向对象编程

    6.1 面向对象编程相关概念 6.1.1 什么是面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。在该思想中程序里万物都是对象。OOP把对象作为程序的基本单元,把具有相同行为的对象归纳成类,通过封装隐藏类的内部细节,通过继承使类得到泛化,通过多态实现基于对象类型的动态分类。封装、继承和多态是…

    Python开发 2023年3月31日
    00
  • 字典(dict)

    4.7 字典(dict) 字典是Python中一种非常重要的数据类型。字典和之前的列表、元组不同,里面的元素使用键-值对进行存储。通常字典中元素的键由字符串或数字等可哈希数据类型组成。可以把字典想象成一个集合,只不过每个元素都是由键-值对组成。字典中的元素的键是不能重复的。字典中的元素也是无序的,这点和集合一样。可以通过键获取集合中元素的值,并且速度要远快于…

    Python开发 2023年4月2日
    00
  • 列表(list)

    4.4 列表(list) 列表是Python中使用最频繁也是最重要最灵活的一种数据结构。Python列表中的元素类型可以不同,可以存放各种各样的数据,比如:数字、字符串、函数、类、字典等,甚至还可以嵌套存放列表。列表也是一种序列,可以通过索引获取列表中的元素。支持序列的各种操作。 4.4.1 列表的创建 4.4.1.1 通过列表标识符号创建 列表在创建的时候…

    Python开发 2023年4月2日
    00
合作推广
合作推广
分享本页
返回顶部