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日

相关文章

  • 面向对象编程

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

    Python开发 2023年3月31日
    00
  • 文档字符串

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

    Python开发 2023年3月31日
    00
  • Python复合语句

    3.6 Python复合语句 复合语句是包含其它语句(语句组)的语句;它们会以某种方式影响或控制所包含其它语句的执行。通常,复合语句会跨越多行,虽然在某些简单形式下整个复合语句也可能包含于一行之内。if、while和for语句用来实现传统的控制流程构造。try语句为一组语句指定异常处理和/和清理代码,而with语句允许在一个代码块周围执行初始化和终结化代码。…

    Python开发 2023年4月2日
    00
  • 类和类的定义

    6.2 类和类的定义 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如学生类,而实例是根据类创建出来的一个个具体的对象,每个对象都拥有相同的方法,但各自的数据可能不同。 6.2.1 什么是类 当你在马路上看到一辆飞驰的奥迪汽车时,这辆奥迪车就是汽车类的一个实例。汽车就是一个类,每辆车都是汽车类的一个实例。可以将…

    Python开发 2023年3月31日
    00
  • Python内置函数

    5.6 Python内置函数 Python自带的所有内置函数如下:Python函数以上为Python3.10中所有的内置函数,其中绝大部分在前面的学习当中都已经接触过了。这里在补充介绍下没有提到或学习到的函数。 5.6.1 callable(object) 描述如果参数 object 是可调用的就返回 True,否则返回 False。 如果返回 True,调…

    2023年3月31日
    00
  • 行走的数字

    一、前言 有一定数学基础的同学们都知道,如果两个正整数相除之后得到的结果,要么能除尽,要么就是一个循环小数。假如结果是循环小数,那么小数的每一位取值是0-9,且存在循环节点。如果我们用小数的每一位进行画图,每位小数用固定的线段表示,而每位小数的大小则用角度(1代表36度,2代表72度,以此类推)表示,这样的话我们就可以看到画图板上有一条线段在行走一样。示例:…

    2023年4月2日
    00
  • 类型转换及相关函数

    4.11 类型转换及相关函数 在Python中,不同的数据类型是可以相互转换的,下面列举一些之前没有介绍但是比较常见的数据类型转换及相关函数,以供参考。 4.11.1 进制转换类 4.11.1.1 bin(x) 描述将整数转变为以“0b”前缀的二进制字符串。示例>>> bin(3)>>> bin(-10) ‘0b11”-…

    Python开发 2023年4月2日
    00
  • Python函数

    5.1 函数相关基础概念 5.1.1 函数是什么 函数是指一段可以直接被另一段程序或代码引用的程序或代码。也叫做子程序、(OOP中)方法。一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现模块的功能。在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。开发者要善于利用函…

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