Python之路【番外篇】回顾&类的静态字段
回顾
回顾:字符串、列表、字典的修改关于内存的情况
一、字符串
str1 = 'luotianshuai'
str2 = str1
print id(str1)
print id(str2)
print '==========================='
str1 = 'shuaige'
print id(str1)
print id(str2) #输出结果:
'''
38807904
38807904
===========================
39795488
38807904
'''
看下我上面的例子,我给str1设置了一个值,并且让str2等于str1。现在他们的值是相等的。
然后我给str1又赋予了一个新的值'shuaige'但是为什么str2的值没有改变呢?
在看下面的例子:
str1 = str('luotianshuai')
str2 = str(str1)
print str1
print str2 print id(str1)
print id(str2) '''
输出结果:
luotianshuai
luotianshuai
41953632
41953632
'''
和上面的例子有什么不同,学完python的面向对象之后,知道python一切实物都是对象,那么咱们在创建字符串的时候是否是创建一个对象呢?是的!
咱们都知道每个对象都是独立的并且存储在内存中的某一块内存空间!
现在在看上面的例子:
我实例化str1的时候生成了一个对象,然后在生成str2的时候有生成了一个对象,然后str2里传的参数是str1。这样str2的内存地址是不是指向了str1
那么如果现在在去想str1 = '新值' 是不是重新实例化,那么他的内存地址是肯定变更了,但是str2会跟着变更吗?咱们知道str1重新实例化的时候并不是在原有的内存块里修改
而是新开辟一块空间!但是他并没有影响str2,str指向的内存地址还是原来的!
二、列表(字典的原理也是相同的)
OK 上面的例子看完了,咱们现在在看列表的例子
list1 = list([11,22,33,44])
list2 = list1
print id(list1)
print id(list1)
print '--------------------'
list1.append(55)
print id(list1)
print id(list2) '''
输出结果:
40970440
40970440
--------------------
40970440
40970440
'''
结合上面的例子,咱们看下为什么list1的值改变后,list2也跟着改变呢?
仔细看的同学能看出来,我这个操作其实并没有给list1重新定义(没有重新实例化,仅仅修改了里面的值)
那么list1和list2的指向也是同一个内存(这个内存里包含了里面元素的内存地址,可以这么理解),对象所指的内存没变,而是对象里面的普通字段变更了!
看下下面的我自己写的类:
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Foo(object):
def __init__(self,string):
self.string = string
def appendstring(self):
self.string = self.string + ' is so shuai' mlist = Foo('tianshuai') mlist2 = mlist
print mlist.string
print mlist2.string
print '--------------------------'
print id(mlist)
print id(mlist2) print '--------------------------'
mlist.appendstring()
print mlist.string
print mlist2.string print '##########################'
print id(mlist)
print id(mlist2) '''
输出结果:
tianshuai
tianshuai
--------------------------
40110848
40110848
--------------------------
tianshuai is so shuai
tianshuai is so shuai
##########################
40110848
40110848
'''
哦也~~ 从这里就应该能看出来了!咱们在操作列表里的元素的时候就相当于操作对象里的普通字段,对象的存在没有被变更变更的仅是对象里存在的字段!
那好现在我在给mlist 重新定义下,现在看下mlist 和mlist2是否相等呢?,看下现在的结果:
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Foo(object):
def __init__(self,string):
self.string = string
def appendstring(self):
self.string = self.string + ' is so shuai' mlist = Foo('tianshuai') mlist2 = mlist
print mlist.string
print mlist2.string
print '--------------------------'
print id(mlist)
print id(mlist2) print '--------------------------'
mlist.appendstring()
print mlist.string
print mlist2.string print '##########################'
print id(mlist)
print id(mlist2) '''
输出结果:
tianshuai
tianshuai
--------------------------
40110848
40110848
--------------------------
tianshuai is so shuai
tianshuai is so shuai
##########################
40110848
40110848
'''
mlist = Foo('new name Tim')
print mlist.string
print mlist2.string
print '------------------'
print id(mlist)
print id(mlist2)
'''
输出结果:
tianshuai
tianshuai
--------------------------
36310656
36310656
--------------------------
tianshuai is so shuai
tianshuai is so shuai
##########################
36310656
36310656
new name Tim
tianshuai is so shuai
------------------
39812232
36310656
'''
OK 了解顺了一遍想当NICE
类的静态字段
关于字符串、列表、字典的回顾和静态字段关系不是很大!只是回顾看下!
一、场景一
首先回顾一下静态字段、普通字段!
class Father(object):
money = 1000 #静态字段 def __init__(self, name): # 普通字段
self.name = name # 直接访问普通字段
obj = Father('laowang')
print obj.name # 直接访问静态字段
print Father.money #普通字段是通过对象来访问的
#静态字段是通过类来访问的
有个这样的需求,老王和小王他们要公用一张银行卡!咱们之前也说过,静态字段是由类来调用的,普通字段是由对象来调用的,咱们看下,当前类成员和对象成员
print obj.__dict__
print Father.__dict__.keys() '''
laowang
1000
------------------------------
{'name': 'laowang'}
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
'''
那你说现在我要用对象去调用这个静态字段是否可以调用呢?是可以的但是有个问题就是,他能调用静态字段,但是他把静态字段当作一个副本存储在对象中了,当对象在修改的时候,并不是修改
的类的静态字段,而是类似修改普通字段!
这也是老师经常说的:静态字段和普通字段的区别是,静态字段是由类调用的普通字段是由对象来调用的!平时操作的时候要注意,不要用对象去操作静态字段
既然普通字段里没有为什么他能找到静态字段呢?
还级的类对象指针吗?他就是通过类对象指针去找的!
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Father(object):
money = 1000 #静态字段 def __init__(self, name): # 普通字段
self.name = name # 直接访问普通字段
obj = Father('laowang')
obj2 = Father('xiaowang')
print obj.name
print obj2.name
# 直接访问静态字段
print Father.money #普通字段是通过对象来访问的
#静态字段是通过类来访问的 print '------------------------------' print obj.__dict__
print obj2.__dict__
print Father.__dict__.keys() '''
laowang
xiaowang
1000
------------------------------
{'name': 'laowang'}
{'name': 'xiaowang'}
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
'''
在这里看下,我现在使用对象来调用静态字段看看!
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Father(object):
money = 1000 #静态字段 def __init__(self, name): # 普通字段
self.name = name # 直接访问普通字段
obj = Father('laowang')
obj2 = Father('xiaowang')
print obj.name
print obj2.name
# 直接访问静态字段
print Father.money #普通字段是通过对象来访问的
#静态字段是通过类来访问的 print '------------------------------' print obj.__dict__
print obj2.__dict__
print Father.__dict__.keys() '''
laowang
xiaowang
1000
------------------------------
{'name': 'laowang'}
{'name': 'xiaowang'}
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
'''
#Father.money = Father.money + 1000000
obj.money = obj.money + 101
obj2.money = obj2.money + 102
print obj.money
print obj2.money
print obj.__dict__
print obj2.__dict__
print Father.__dict__.keys() '''
输出结果:
laowang
xiaowang
1000
------------------------------
{'name': 'laowang'}
{'name': 'xiaowang'}
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
1101
1102
{'money': 1101, 'name': 'laowang'}
{'money': 1102, 'name': 'xiaowang'}
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
'''
从输出结果中就能看出来!当对象在去修改这个字段的时候,他首先会在自己那里找下(普通字段是存在对象中的),如果没有他就会通过类对象指针去查找字段发现类中有一个“静态字段”,这个静态字段的名称和咱们在对象输入的名称相同
他会把复制一下这个静态字段的信息保存到对象中,那么现在保存在对象中的这个”静态字段“还是静态字段吗?还是一个普通字段?
说了这么多的作用是什么:
在调用静态字段的时候不要用对象去调用。除非你想把静态字段在对象中使用并且当作普通字段来使用!如果你想要修该静态字段,应该使用类来调用!
并且注意下,我还测试了一个,如果一个类中,有普通字段和静态字段(两个是同名的)你对象在调用这个字段的时候调用的肯定是自己的普通字段,当然也有办法调用静态字段!
class Father(object):
money = 1000
def __init__(self,name,money):
self.name = name
self.money = money father_obj1 = Father('shuai',100) #实例化一个对象
print Father.__dict__.keys() #类中的成员
print father_obj1.__dict__ #对象中的成员 print Father.money #调用静态字段
print father_obj1.money #这么调用只能调用普通字段
print father_obj1.__class__.money #这个可以用这个方法让对象调用静态字段 '''
输出结果:
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
{'money': 100, 'name': 'shuai'}
1000
100
1000 '''
二、场景二
考虑一个问题,同样是这个类,我现在要写两个派生类!你说能从派生类里,去修改基类的静态字段吗?
看下下面的例子:(关于对象修改静态字段我就不在重复了)
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Father(object):
money = 1000 #静态字段 def __init__(self, name): # 普通字段
self.name = name class Child(Father):
pass
class Child2(Father):
pass print Father.__dict__.keys()
print Child.__dict__
print Child2.__dict__
'''
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
{'__module__': '__main__', '__doc__': None}
{'__module__': '__main__', '__doc__': None}
'''
我先打印一下,当前基类中和派生类中的成员,可以看出,如果派生类不调用或实例化的话是不会向父类那里获取相关方法或参数的!
好看下,我现在在派生类中,用派生类去修改静态方法!然后打印一下,现在派生类中的成员,基类的静态字段会改变吗?
#!/usr/bin/env python
#-*- coding:utf-8 -*- class Father(object):
money = 1000 #静态字段 def __init__(self, name): # 普通字段
self.name = name class Child(Father):
pass
class Child2(Father):
pass print Father.__dict__.keys()
print Child.__dict__
print Child2.__dict__
'''
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
{'__module__': '__main__', '__doc__': None}
{'__module__': '__main__', '__doc__': None}
'''
Child.money = Child.money + 100
Child2.money = Child2.money + 102 print Father.money
print Child.money
print Child2.money print Father.__dict__.keys()
print Child.__dict__.keys()
print Child2.__dict__.keys() '''
输出结果:
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
{'__module__': '__main__', '__doc__': None}
{'__module__': '__main__', '__doc__': None}
1000
1100
1102
['__module__', 'money', '__dict__', '__weakref__', '__doc__', '__init__']
['money', '__module__', '__doc__']
['money', '__module__', '__doc__']
'''
从结果可以看出,你在修改派生类中的静态字段的时候,其实也是相当于在基类中复制了一个副本。下次在调用派生类的时候直接在自己的类中调就可以了不会在去基类中查找!
说这个的目的是什么:
如果你想在派生类中想修改基类的静态方法的时候,不要调用派生类中的静态字段,需要调用基类的静态字段!
Python之路【番外篇】回顾&类的静态字段的更多相关文章
- python的类和对象——番外篇(类的静态字段)
什么是静态字段 在开始之前,先上图,解释一下什么是类的静态字段(我有的时候会叫它类的静态变量,总之说的都是它.后面大多数情况可能会简称为类变量.): 我们看上面的例子,这里的money就是静态字段,首 ...
- Python之路番外:PYTHON基本数据类型和小知识点
Python之路番外:PYTHON基本数据类型和小知识点 一.基础小知识点 1.如果一行代码过长,可以用续行符 \换行书写 例子 if (signal == "red") and ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- python自动化测试应用-番外篇--接口测试2
篇2 book-python-auto-test-番外篇--接口测试2 --lamecho辣么丑 大家好! 我是lamecho(辣么丑),今天将继续上一篇python接 ...
- python自动化测试应用-番外篇--接口测试1
篇1 book-python-auto-test-番外篇--接口测试1 --lamecho辣么丑 1.1概要 大家好! 我是lamecho(辣么丑),至今<安卓a ...
- python之爬虫--番外篇(一)进程,线程的初步了解
整理这番外篇的原因是希望能够让爬虫的朋友更加理解这块内容,因为爬虫爬取数据可能很简单,但是如何高效持久的爬,利用进程,线程,以及异步IO,其实很多人和我一样,故整理此系列番外篇 一.进程 程序并不能单 ...
- Python之路(第二十三篇) 面向对象初级:静态属性、静态方法、类方法
一.静态属性 静态属性相当于数据属性. 用@property语法糖装饰器将类的函数属性变成可以不用加括号直接的类似数据属性. 可以封装逻辑,让用户感觉是在调用一个普通的数据属性. 例子 class R ...
- Python之路番外(第二篇):PYTHON基本数据类型和小知识点
一.基础小知识点 1.如果一行代码过长,可以用续行符 \换行书写 例子 if (signal == "red") and \ (car == "moving") ...
- Python之路番外(第三篇):Pycharm的使用秘籍
版本:Pycharm2017.3.4Professional Edition 一.Pycharm的基本使用1.在Pycharm下为你的python项目配置python解释器 file --settin ...
随机推荐
- Jquery ui autocomplete简单api
重要说明:与配置选项类似,Autocomplete插件的方法也不是直接调用,而且通过autocomplete()方法进行间接调用.例如: $("#title").autocompl ...
- js学习笔记5----函数传参
构建函数的原则: 1) 尽量保持HTML结构一致: 2) 把核心主程序实现,用函数包起来: 3) 把每组里不同的值找出来,通过传参实现.
- BZOJ 1103: [POI2007]大都市meg
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2189 Solved: 1160[Submit][Sta ...
- 【faster-rcnn】训练自己的数据集时的坑
既然faster-rcnn原版发表时候是matlab版代码,那就用matlab版代码吧!不过遇到的坑挺多的,不知道python版会不会好一点. ======= update ========= 总体上 ...
- .net config文件 配置类的集合
1,appconfig文件 <configSections> <section name="ToolConfig" type="DMTools.Tool ...
- Linux下的删除命令
Linux:rm Windows:del rm parameter: -f, --force 忽略不存在的文件,从不给出提示.-i, --interactive 进行交互式删除-r, -R, - ...
- 环信webim1.1.2版本在windows下npm环境搭建错误解决
1.1.2版本的webim从ui到整体的代码结构都做了很大改变,从代码结构上采用node.js的环境进行开发和打包,最终打包的输出项目,不依赖node.js的环境进行运行,得益于webpack的打包实 ...
- 正则表达式re模块
正则表达式模块re 1. 正则简介 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言, (在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被 编译 ...
- 【Alpha版本】 第八天 11.16
一.站立式会议照片: 二.项目燃尽图: 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 完成我要应聘的列表显示,完成账户信息设置界面 完成我要应聘的详情显 ...
- HTML5学习总结-01 开发环境和历史
1 搭建HTML5开发环境 1 安装一款支持HTML5的浏览器 FireFox, Chrome 2 开发工具 SublineText, Eclipse, HBuilder, WebStorm 注:使用 ...