python静态字段_Python之路【番外篇】回顾&类的静态字段

回顾

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

一、字符串

str1 = 'luotianshuai'str2=str1printid(str1)printid(str2)print '==========================='str1= 'shuaige'

printid(str1)printid(str2)#输出结果:

'''38807904

38807904

===========================

39795488

38807904'''

看下我上面的例子,我给str1设置了一个值,并且让str2等于str1。现在他们的值是相等的。

然后我给str1又赋予了一个新的值'shuaige'但是为什么str2的值没有改变呢?

在看下面的例子:

str1 = str('luotianshuai')

str2=str(str1)printstr1printstr2printid(str1)printid(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=list1printid(list1)printid(list1)print '--------------------'list1.append(55)printid(list1)printid(list2)'''输出结果:

40970440

40970440

--------------------

40970440

40970440'''

结合上面的例子,咱们看下为什么list1的值改变后,list2也跟着改变呢?

仔细看的同学能看出来,我这个操作其实并没有给list1重新定义(没有重新实例化,仅仅修改了里面的值)

那么list1和list2的指向也是同一个内存(这个内存里包含了里面元素的内存地址,可以这么理解),对象所指的内存没变,而是对象里面的普通字段变更了!

看下下面的我自己写的类:

#!/usr/bin/env python#-*- coding:utf-8 -*-

classFoo(object):def __init__(self,string):

self.string=stringdefappendstring(self):

self.string= self.string + 'is so shuai'mlist= Foo('tianshuai')

mlist2=mlistprintmlist.stringprintmlist2.stringprint '--------------------------'

printid(mlist)printid(mlist2)print '--------------------------'mlist.appendstring()printmlist.stringprintmlist2.stringprint '##########################'

printid(mlist)printid(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 -*-

classFoo(object):def __init__(self,string):

self.string=stringdefappendstring(self):

self.string= self.string + 'is so shuai'mlist= Foo('tianshuai')

mlist2=mlistprintmlist.stringprintmlist2.stringprint '--------------------------'

printid(mlist)printid(mlist2)print '--------------------------'mlist.appendstring()printmlist.stringprintmlist2.stringprint '##########################'

printid(mlist)printid(mlist2)'''输出结果:

tianshuai

tianshuai

--------------------------

40110848

40110848

--------------------------

tianshuai is so shuai

tianshuai is so shuai

##########################

40110848

40110848'''mlist= Foo('new name Tim')printmlist.stringprintmlist2.stringprint '------------------'

printid(mlist)printid(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

类的静态字段

关于字符串、列表、字典的回顾和静态字段关系不是很大!只是回顾看下!

一、场景一

首先回顾一下静态字段、普通字段!

classFather(object):

money= 1000 #静态字段

def __init__(self, name):#普通字段

self.name =name#直接访问普通字段

obj = Father('laowang')printobj.name#直接访问静态字段

printFather.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 -*-

classFather(object):

money= 1000 #静态字段

def __init__(self, name):#普通字段

self.name =name#直接访问普通字段

obj = Father('laowang')

obj2= Father('xiaowang')printobj.nameprintobj2.name#直接访问静态字段

printFather.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 -*-

classFather(object):

money= 1000 #静态字段

def __init__(self, name):#普通字段

self.name =name#直接访问普通字段

obj = Father('laowang')

obj2= Father('xiaowang')printobj.nameprintobj2.name#直接访问静态字段

printFather.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 + 101obj2.money= obj2.money + 102

printobj.moneyprintobj2.moneyprint 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__']'''

从输出结果中就能看出来!当对象在去修改这个字段的时候,他首先会在自己那里找下(普通字段是存在对象中的),如果没有他就会通过类对象指针去查找字段发现类中有一个“静态字段”,这个静态字段的名称和咱们在对象输入的名称相同

他会把复制一下这个静态字段的信息保存到对象中,那么现在保存在对象中的这个”静态字段“还是静态字段吗?还是一个普通字段?

说了这么多的作用是什么:

在调用静态字段的时候不要用对象去调用。除非你想把静态字段在对象中使用并且当作普通字段来使用!如果你想要修该静态字段,应该使用类来调用!

并且注意下,我还测试了一个,如果一个类中,有普通字段和静态字段(两个是同名的)你对象在调用这个字段的时候调用的肯定是自己的普通字段,当然也有办法调用静态字段!

classFather(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 -*-

classFather(object):

money= 1000 #静态字段

def __init__(self, name):#普通字段

self.name =nameclassChild(Father):pass

classChild2(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 -*-

classFather(object):

money= 1000 #静态字段

def __init__(self, name):#普通字段

self.name =nameclassChild(Father):pass

classChild2(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 + 100Child2.money= Child2.money + 102

printFather.moneyprintChild.moneyprintChild2.moneyprint 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__']'''

从结果可以看出,你在修改派生类中的静态字段的时候,其实也是相当于在基类中复制了一个副本。下次在调用派生类的时候直接在自己的类中调就可以了不会在去基类中查找!

说这个的目的是什么:

如果你想在派生类中想修改基类的静态方法的时候,不要调用派生类中的静态字段,需要调用基类的静态字段!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值