回顾

回顾:字符串、列表、字典的修改关于内存的情况

一、字符串

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之路【番外篇】回顾&类的静态字段的更多相关文章

  1. python的类和对象——番外篇(类的静态字段)

    什么是静态字段 在开始之前,先上图,解释一下什么是类的静态字段(我有的时候会叫它类的静态变量,总之说的都是它.后面大多数情况可能会简称为类变量.): 我们看上面的例子,这里的money就是静态字段,首 ...

  2. Python之路番外:PYTHON基本数据类型和小知识点

    Python之路番外:PYTHON基本数据类型和小知识点 一.基础小知识点 1.如果一行代码过长,可以用续行符 \换行书写 例子 if (signal == "red") and ...

  3. 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV

    这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...

  4. python自动化测试应用-番外篇--接口测试2

    篇2                 book-python-auto-test-番外篇--接口测试2 --lamecho辣么丑 大家好! 我是lamecho(辣么丑),今天将继续上一篇python接 ...

  5. python自动化测试应用-番外篇--接口测试1

    篇1                 book-python-auto-test-番外篇--接口测试1 --lamecho辣么丑 1.1概要 大家好! 我是lamecho(辣么丑),至今<安卓a ...

  6. python之爬虫--番外篇(一)进程,线程的初步了解

    整理这番外篇的原因是希望能够让爬虫的朋友更加理解这块内容,因为爬虫爬取数据可能很简单,但是如何高效持久的爬,利用进程,线程,以及异步IO,其实很多人和我一样,故整理此系列番外篇 一.进程 程序并不能单 ...

  7. Python之路(第二十三篇) 面向对象初级:静态属性、静态方法、类方法

    一.静态属性 静态属性相当于数据属性. 用@property语法糖装饰器将类的函数属性变成可以不用加括号直接的类似数据属性. 可以封装逻辑,让用户感觉是在调用一个普通的数据属性. 例子 class R ...

  8. Python之路番外(第二篇):PYTHON基本数据类型和小知识点

    一.基础小知识点 1.如果一行代码过长,可以用续行符 \换行书写 例子 if (signal == "red") and \ (car == "moving") ...

  9. Python之路番外(第三篇):Pycharm的使用秘籍

    版本:Pycharm2017.3.4Professional Edition 一.Pycharm的基本使用1.在Pycharm下为你的python项目配置python解释器 file --settin ...

随机推荐

  1. DOS命令行下mysql 基本命令

    第一招.mysql服务的启动和停止 net stop mysql net start mysql 第二招.登陆mysql 语法如下: mysql -u用户名 -p用户密码 键入命令mysql -uro ...

  2. SpringMVC与Struts2区别与比较总结

    1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上Spr ...

  3. 回合对战制游戏第一篇(初识java)

    回合对战制游戏第一篇 一,所谓的java. java是一门完全面向对象的编程语言,而之前所接触到的C语言是一门面向有一个过程的语音,对于两个的区别应该有一个清楚的认识. java的第一个内容. 类和对 ...

  4. 当findById(Integer id)变成String类型

    1.原Action // 添加跳转 @RequiresPermissions("pdaManager:v_add") @RequestMapping("/pdaManag ...

  5. js-JavaScript高级程序设计学习笔记18

    第21章 AJAX 4.跨域源资源共享 CORS跨域源资源共享,其背后思想,是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是否应该成功. 1.IE对CORS的实现 在IE8中引 ...

  6. 前端打包/自动化构建工具:fis3

    据说这个可以进行打包,并且可以实现类似/script/test-adsf123.js或者/script/test.js?v=asdf123 先做个记号 参考:http://fis.baidu.com/

  7. git恢复误删文件及省去密码提交

    自己遇到这种情况:自己将某文件在网页的控制面板上直接删除了,再pull下来.或者一个成员误删除了某个文件,然后push到远程库了,其他成员也都pull了,结果就是所有人的本地库当前版本中这个文件都不见 ...

  8. Capture

    1.导出Logical symbol 单个元件导出放入指定库:左键选中元件→右键“Edit Parts”→View“Package”→file“Save As”→找到要存放的库. 从某个已经设计好的原 ...

  9. F7控件

    //动态给F7加过滤 waf("#costSubject").wafPromptStandard("option", "filteritem" ...

  10. iptables log

    iptables 日志 LOG target 这个功能是通过内核的日志工具完成的(rsyslogd) LOG现有5个选项 --log-level debug,info,notice,warning,w ...