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中的也会改变,最后演示了一下,列表中的元组,元组本身不可变,所以更改元组中内容会报错,且传递的是值,但是这个元组作为一个列表中的元素,我们可以整体替换掉。

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

(待续)

时间: 2024-10-27 07:34:00

Python查缺补漏之动态实例属性的相关文章

Python缺乏调查的陷阱 动态实例属性、引用、逃生

--看到哪里.想到哪里,记到哪里 非常多时候.非常多人学python的时候,会忽略的东西非常多.大多数都盯着能"出货"即可,可是通常在读别人的代码的时候发现,看不懂...一方面是自己的代码技巧和经验不足:还有一方面就是自己掌握的东西不全面.而这些往往是基础的东西.还不算高大上的东西.. 第一:动态实例属性 Python的类,面向对象的东西和其它语言不太一样.比方实例的属性是能够动态分配的.本来没有的.能够自己加上,就算类中未定义,也能够用,挺方便的.可是建议能一次行定义完整最好,以下举

Android查缺补漏(View篇)--自定义 View 的基本流程

View是Android很重要的一部分,常用的View有Button.TextView.EditView.ListView.GridView.各种layout等等,开发者通过对这些View的各种组合以形成丰富多彩的交互界面,一个应用中界面交互的体验往往在应用的受欢迎程度上起了很关键得作用,所以开发者们大多会想方设法的做出一个更加精美的界面,例如:通过自定义View.深入学习View的原理以便更好的对其优化使其在操作起来更加流畅等等,也正因为如此,在面试中View也常常作为面试官重点考察的对象之一

React查缺补漏之二

译文链接 通过给一个通用函数传入参数定制特定函数的用法 _onFieldChange函数是一个通用实例方法,通过给这个函数传入不同的参数来实现返回结果的不同. 在构造函数中,进行绑定(没有想过这种用法). 1. `this._onNameChanged = this._onFieldChange.bind(this, 'name');` 2. `this._onPasswordChanged =this._onFieldChange.bind(this, 'password');` **注意点击

Android查缺补漏--Service和IntentService

Service的运行不依赖界面,即使程序被切换到后台,Service仍然能够保持正常运行.当某个应用程序进程被杀掉时,所有依赖于该进程的Service也会停止运行. Service 分为启动状态和绑定状态.当处于仅启动状态时,通过 stopService或 stopSelf 即可停止 Service.当处于绑定状态时需要通过 unBindService 和 stopService 结合使用才能完全停止 Service. 一.Service的生命周期(onCreate()-onStartComma

Android查缺补漏--ContentProvider的使用

ContentProvider (内容提供者)是一种共享型组件,可以为系统内应用于与应用之间提供访问接口. ContentProvide要想正常工作需要三个关键点: ContentProvider:对外提供数据的访问接口. Uri:ContentProvider的唯一标识,外界可根据其访问对应的ContentProvider. ContentResolver 比如,当应用A想把自己数据暴露出来让别的应用也可以操作的话,就可以在应用A内部创建一个ContentProvider实现相关方法并添加UR

Android查缺补漏(View篇)--在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0?

在 Activity 的 onCreate() 方法中为什么获取 View 的宽和高为0 ? @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_view); myview = ViewUtils.find(this, R.id.myview); getViewSize("onCr

Android查缺补漏(View篇)--自定义View利器Canvas和Paint详解

上篇文章介绍了自定义View的创建流程,从宏观上给出了一个自定义View的创建步骤,本篇是上一篇文章的延续,介绍了自定义View中两个必不可少的工具Canvas和Paint,从细节上更进一步的讲解自定义View的详细绘制方法.如果把自定义View比作盖一座房子,那么上篇文章就相当于教会了我们怎么一步步的搭建房子的骨架,而本篇文章将要教会我们的是为房子的骨架添砖加瓦直至成型,甚至是怎么装修. Canvas 为了后文更为方便的讲解Canvas的常用方法的使用,我们先来做一些准备工作,创建一个自定义V

Android查缺补漏(View篇)--事件分发机制源码分析

在上一篇博文中分析了事件分发的流程及规则,本篇会从源码的角度更进一步理解事件分发机制的原理,如果对事件分发规则还不太清楚的童鞋,建议先看一下上一篇博文 <Android查缺补漏(View篇)--事件分发机制> ,先来看一下本篇的分析思路,一会儿会按照事件传递的顺序,针对以下几点进行源码分析: Activity对点击事件的分发过程 PhoneWindow是如何处理点击事件的 顶级View对点击事件的分发过程 View对点击事件的处理过程 Activity对点击事件的分发过程 通过上一篇博文中我们

20165306 第二周查缺补漏

第二周查缺补漏 1.位运算符 位运算符主要针对两个二进制数的位进行逻辑运算,所以要先把其他进制数转化为二进制数. 例如: 128&129 128转换成二进制就是10000000,129转换成二进制就是10000001,根据与运算符的运算规律,"只有两个位都是1,结果才是1",可以知道结果就是10000000,即128. 128|129 根据或运算符的运算规律,"只要两个位有一个是1,结果就是1",可以知道结果就是10000001,即129. 15^2 15转