Python查缺补漏之一 动态实例属性、引用、转义

——看到哪里,想到哪里,记到哪里

很多时候,很多人学python的时候,会忽略的东西很多,大多数都盯着能“出货”就行,但是通常在读别人的代码的时候发现,看不懂。。。一方面是自己的代码技巧和经验不足;另一方面就是自己掌握的东西不全面,而这些往往是基础的东西,还不算高大上的东西。。

第一:动态实例属性

Python的类,面向对象的东西和其他语言不太一样,比如实例的属性是可以动态分配的,本来没有的,可以自己加上,就算类中没有定义,也可以用,挺方便的,但是建议能一次行定义完整最好,下面举个粒子:

>>> class Address(object):
...         def __init__(self,name,phone):
...               self.name = name
...               self.phone = phone
... 
>>> jhon = Address('Jhon dov','123456')
>>> jhon.name
'Jhon dov'
>>> jhon.phone
'123456'
>>> jhon.wa = 'aaa'
>>> print jhon.wa
aaa
jhon.wa这个,就是实例属性的动态分配,原来类中没有定义wa属性,但是我们可以通过jhon实例创建一个。。

第二,可变不可变,传引用传值

到底传值还是传引用。。有时候会乱,那是因为理解不深刻啊,python中还是很好区分的,举个粒子:

>>> list1 = [1,'a',['foo','bar'],('cc','opo')]
>>> list2 = list1
>>> list2[0]
1
>>> list2[2]
['foo', 'bar']
>>> list2[3]
('cc', 'opo')
>>> list2[3][0]
'cc'
>>> list2[0] = 2
>>> list2[2][0] = 'wang'
>>> list1
[2, 'a', ['wang', 'bar'], ('cc', 'opo')]
>>> list2
[2, 'a', ['wang', 'bar'], ('cc', 'opo')]
>>> list1[3][0] = 'dd'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
可以看出来,直接赋值的这种传的是引用,就是说list1、list2指向的是内存中相同的地方,就像一个人取了俩名字,这点还是很好理解的

再来个栗子:

>>> alist = list(list1)
>>> alist
[2, 'a', ['wang', 'bar'], ('cc', 'opo')]
>>> list1
[2, 'a', ['wang', 'bar'], ('cc', 'opo')]
>>> alist[0] = 3
>>> alist[1] = 'Z'
>>> alist[2][1] = "rab"
>>> alist[3][0] = "111"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> alist[3] = ['1','2','3']
>>> alist
[3, 'Z', ['wang', 'rab'], ['1', '2', '3']]
>>> list1
[2, 'a', ['wang', 'rab'], ('cc', 'opo')]
这次不是直接赋值,但是一开始我们比较alist和list1,发现内容一样的,往下看,当对alist中的前两个元素更改的时候,最后与list1不一样了,list1的前两个元素没变,alist变了,这是因为前两个元素,一个是整数一个是字符串,都是不可变的,所以,alist中的前两个元素其实是list1前两个元素的传值的效果,就是说两者只是值相同,内存中有两份,但是内存中的位置不一样,所以更改alist中的前两个元素时,不影响list1中的;再看list1中的['wang','bar'],这本身就是个列表,我们知道,列表是可变的,所以在python中,这个列表传的是引用,内存中只有一份,所以,改变alist中的这个列表,list1中的也会改变,最后演示了一下,列表中的元组,元组本身不可变,所以更改元组中内容会报错,且传递的是值,但是这个元组作为一个列表中的元素,我们可以整体替换掉。

可能说的比较乱,自己动手试试就知道了,这就是一个“浅拷贝”和“深拷贝”问题,浅拷贝顾名思义,拷贝的很浅,可以理解为倒卖指针的家伙,同喝一杯饮料,就是传引用,再具体点的栗子就是,借别人一个东西,不管怎么借,东西就是一个,不会自己增加,如果有人把借的东西用坏了,那就真坏了;深拷贝,传值,每个人一杯饮料,举个栗子就是,你看见别人一个杯子很好看,你也想有一个,于是你也买了一个一样的杯子,两个杯子是一样的,但是所属人不一样,如果你不小心把杯子弄啐了,别人的杯子是不可能也跟着坏的。。。

第三,字符串抑制转义

新手一开始在读别人代码的时候,特别是读写文件那部分,总会遇到转义的问题,还有不明白转义是什么的也不在少数,照猫画虎的也有,真正理解其实很简单就是‘\’与其他字符拼在一起的时候,会变成其他的含义,下图给了几个例子

还有一个明显且常见的,file = open('C:\new\text.dat','w'),我们认为这是打开此目录下的dat文件,但是这样不行,因为\n是换行符,\t是制表符,那怎么解决?

一个通用的方法就是:字符串抑制转义,用法如:

file = open(r'C:\new\text.dat','w')
解释:如果r(大写或者小写)出现在字符串的第一个引号的前面,将会自动关闭转义机制

还可以这样解决:

file = open('C:\\new\\text.dat','w')
其实这两种方式基本一样,如:

>>> path = r'C:\new\text.dat'
>>> path
'C:\\new\\text.dat'
>>> print path
C:\new\text.dat
>>> 






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值