回顾

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

一、字符串

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. Docker指定multiple Insecure registry的方法

    Docker如果需要从非SSL源管理镜像,需要配置Docker配置文件的insecury-registry参数,一般在如下位置修改其配置文件: * /etc/sysconfig/docker * /e ...

  2. C# asp.net mvc 配置多个route 参数

    mvc 中路由可以自定义 public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { ...

  3. 机器学习Python包

    随着机器学习的逐日升温,各种相关开源包也是层出不群,面对如此多种类的工具包,该如何选择,有的甚至还知之甚少或者不知呢,本文简单汇总了一下当下使用比较多的Python版本机器学习工具包,供大家参看,还很 ...

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

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

  5. 53. Android常用工具类

    主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java.目前包括HttpUtils.DownloadManagerPro.ShellUtils.PackageUtils.Prefer ...

  6. 主机和虚拟机能相互ping通但是不能复制

    1.本机能ping通虚拟机 2.虚拟机也能ping通本机 3.虚拟机能访问自己的web 4.本机无法访问虚拟己的web 后来发现是防火墙将80端口屏蔽了的缘故. 检查是不是服务器的80端口被防火墙堵了 ...

  7. springMVC-错误消息的显示和国际化

    显示:在页面添加<form:errors path="*">会把错误消息集中显示在一块 在页面添加<form:errors path="lastname ...

  8. 51nod比赛

    http://www.cnblogs.com/wzj-is-a-juruo/p/5619901.html

  9. Python基础1:if条件判断 break/continue语句

    计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. Python中,if语句被用来进行判断,它的语法结构是: 1 if 判断条件: 2 执行语句…… 3 var = input(" ...

  10. Centos下查看占用端口并关闭进程方法

    1.查看端口占用情况:netstat –tlnp   (加p可以看到是哪个进程占用了端口); 也可以用grep查找对应的被占用的端口,键入netstat –tlnp | grep 3306可以看到PI ...