python编程基础——简单语句

本文深入讲解Python编程中的关键概念,包括模块导入、元组赋值、变量交换、==与is的区别,以及Python内部机制如intern机制和字符串处理的细节。

import引入

在python编程中经常用到import引入模块,引入方法如下几种:

# 直接引入模块
>>> import math
>>> math.pwo(2,3)
>>> math.pow(2,3)
8.0

# 引入模块中的函数
>>> from math import pow
>>> pow(2,3)
8.0

# 重命名引入的模块函数
>>> from math import pow as p
>>> p(2,3)
8.0

# 批量引入模块中的函数
>>> from math import pow,e,pi
>>> e
2.718281828459045
>>> pi
3.141592653589793

# 引入模块中所以的函数
>>> pow(2,3)
8.0
>>> sqrt(9)
3.0


赋值

在编程中 " = "表示赋值,这一点之前已经在前面几篇博客中涉及过了。这里将更深入介绍赋值。

通过赋值定义元组

>>> tup='a',1,'qwed',"asd sdw"
>>> tup
('a', 1, 'qwed', 'asd sdw')

变量交换

>>> a=1
>>> b=2
>>> a,b=b,a
>>> a
2
>>> b
1

==和is

“ == ”是用于判断值是否相等
” is “是用于判断引用是否相等

>>> a="I use python"
>>> b="I use python"
>>> id(a)
1923428064432
>>> id(b)
1923428147696
>>> a is b
False
>>> a==b
True


补充

感谢 “二段高雅”、“ascasf” 对博主的留言评论,为此博主也是查阅了相关资料,写了如下补充,由于本人能力有限,如有错误还望不吝赐教。

Q:能解释下is吗?

A:在回答这个问题之前,先让我们简单回顾一些python的数据对象。在python中,所有的数据都表示为对象及对象之间的关系。。每个对象都由其标志(identity)、类型(type)、和值(value)三者标识。

  • 标志 用于唯一标识对象,可将标志看作对象在计算机内存地址
  • 类型 用于限定对象的行为——对象所表示的取值范围以及允许执行的操作集合。
  • 值 用于表示对象数据类型的值

感觉有点迷?没关系让我们举个栗子就明白了。首先在内存空间划分一块区域,创建一个值为4321int类型对象,然后将变量a绑定(即让a使用该对象的标志1957571188752)到新建的int对象。其中id()返回的就是该对象的标志(即内存)。

a = 4321
print(a)
print(type(a))
print(id(a))
a = 1234
print(a)
print(type(a))
print(id(a))

输出结果
1234
<class 'int'>
1957571188752
4321
<class 'int'>
1957571188176

为了更加直观的描述,我画了一个图,从下图可以看出,第一个赋值语句a=1234,创建一个值为1234的int对象,然后将变量a绑定到新建的int对象。第一个赋值语句a=4321,是创建创建一个值为4321的int对象,然后将变量a绑定到4321这个新建的int对象。此时原来的对象4321无变量引用,不过无需处理,python的回收机制会自动回收。
示例图

我们会发现,在python中变量真正存放的就是被引用对象的标志(内存地址),而is则是用来判断不同变量的引用对象是不是同一个。而==则是判断不同变量的引用对象的值是否相同。




Q:能够详细解释一下相同字符串的id()为什么会不一样吗?

A:在python中的对象分为可变对象和不可变对象。int 、float、 str 、tuple、boole 都是不可变对象,list、set、dict都是可变对象。

  • 不可变对象是指一旦该对象创建就不能改变了
    如上问图所示,对于a所引用的int类型值为4321的对象,如果我们想让这个被引用的对象变为1234,是不能在源地址上对4321修改的。我们只能通过创建一个新的int类型值为1234的对象,并将1234这个对象的标志(内存地址)绑定到变量a。

如果让你创建5个“helloworld”,你会怎么创建,无外乎有下面两种:
对于方案一 python需要为相同的字符串对象创建五次每一次都是创建完成后将该对象绑定到相应的变量(因此这几个变量的id都是不一样的,因为没有被绑定到同一个内存地址上),方案二则是只创建了一次,并将该对象绑定到了五个变量上去(这五个变量的地址是一样的,所以id也是一样的)。
在这里插入图片描述



这时候发现原来的单词拼写错了,a0-a4这些变量需要改成helloworld,这时又该怎么做呢?对于方案一,我们需要像处理a0这样先创建一个helloworld对象,然后把这个对象绑定到变量上,而对于方案二,我们需要先检验一下helloworld有没有存在,如果存在了则把把它绑定到变量上,没有则创建对象,然后再绑定。

在这里插入图片描述
因此,如果能合理的控制查找字符串的速度(如果字符串过长那么维护起来就很麻烦,每次查找都要很长时间的检查,还不如直接创建来的舒服),那么在创建变量时就能既快速又节约内存。


intern机制
因此Python解释器为了提高字符串使用的效率和使用性能,使用 intern(字符串驻留)的技术来提高字符串效率,即把合适的字符串对象放在字符串储蓄池中,这个池子是一个字典结构,如果字符串已经存在于池子中就不再去创建新的字符串,直接返回之前创建好的字符串对象,如果之前还没有加入到该池子中,则先构造一个字符串对象,并把这个对象加入到池子中去,方便下一次获取。避免频繁的创建和销毁内存,提升效率。这也决定了字符串必须是不可变对象。



那么哪些情况下使用了intern机制呢?

  • 小整数和字母
    python对小整数的定义是[-5,257]这些整数对象是提前建立好的,不会被垃圾回收。在一个Python的程序中,所有位于这个范围内的整数使用的都是同一个对象。同理,单个字符也是这样的。
# 小整数
>>> a=1
>>> id(a)
(140706394051392,140706394051392)
# 单个字符
>>> a='a'
>>> b='a'
>>> id(a),id(b)
(1588040673296, 1588040673296)
>>> a=' '
>>> b=' '
>>> id(a),id(b)
(2126280417888, 2126280417888)
# 即便没有对象引用‘a’了也不会被垃圾回收
>>> a='a'
>>> b='a'
>>> id(a),id(b)
(1588040673296, 1588040673296) #上一次也是(1588040673296, 1588040673296)
  • 字符串(由字母数字下划线构成)
    python对由大小写字母,下划线,数字构成的字符串会主动使用intern机制。共用对象,引用计数为0时,则销毁。
# 由字母数字下划线构成
>>> a='asd'
>>> b='asd'
>>> id(a,b)
>>> id(a),id(b)
(2126286028672, 2126286028672)
>>> a='asd1_'
>>> b='asd1_'
>>> id(a),id(b)
(1588049273720, 1588049273720)
# 此时的字符串‘asd’已经没有被变量引用,所以已经被python垃圾回收机制回收了,从池中删除,再次创建则会重新加入到字符串储蓄池中。
>>> a='asd'
>>> b='asd'
>>> id(a),id(b)
(1588049275232, 1588049275232) #上一次是(2126286028672, 2126286028672)


  • 其他字符
    如果字符串中含有数字字母下划线以外的字符,则不会主动触发intern机制。而是分别划分了内存地址用于存储数据。
>>> a='asd '
>>> b='asd '
>>> id(a),id(b)
(2032754015008, 2032759079240)
>>> a='!@#'
>>> b='!@#'
>>> id(a),id(b)
(2032759081032, 2032759081592)

思考

值得注意的是以上代码都是在交互式界面运行的。如果通过脚本方式运行还会一样吗?
我们将下面这段代码保存为test.py文件,运行会发惊奇的发现a和b的id居然一样,(在pycharm运行也是以脚本形势运行的)

a='asd  '
b='asd  '
print(id(a),id(b))
C:\Users\xu.shi\Desktop>python test.py
2454798883560 2454798883560

这是因为在运行一个.py文件时,会对整体代码进行优化,这样做的目的就是为了将代码进行优化以加快运行速度。这是在交互式界面运行所没有的(因为交互式是按行运行)

评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值