Python变量、方法(静态、类、实例、全局、局部)超全详细解析

Python变量、方法(静态、类、实例、全局、局部)超全详细解析

基础概念

a、全局变量:在模块内、在所有函数外面、在class外面,这就是全局变量。
b、局部变量:在函数内、在class的方法内(未加self修饰的),这就是局部变量
c、 静态变量:在class内的,但不在class的方法内的,这就是静态变量
d、 实例变量:在class的方法内的,用self修饰的变量,这就是实例变量

全局变量-引用

使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字

# -*- coding:utf-8 -*-
a = 1
b = [2, 3]

def func():
    a = 2
    print "in func a:", a
    b[0] = 1
    b.append(6)
    print "in func b:", b

if __name__ == '__main__':
    print "before func a:", a
    print "before func b:", b
    func()
    print "after func a:", a
    print "after func b:", b
before func a: 1
before func b: [2, 3]
in func a: 2
in func b: [1, 3, 6]
after func a: 1
after func b: [1, 3, 6]

全局变量-修改

要修改全局变量,可以使用全局变量,之前加入global声明

a = 1
b = [2, 3]

def func():
    global a
    a = 2
    print "in func a:", a
    b[0] = 1
    print "in func b:", b

if __name__ == '__main__':
    print "before func a:", a
    print "before func b:", b
    func()
    print "after func a:", a
    print "after func b:", b
before func a: 1
before func b: [2, 3]
in func a: 2
in func b: [1, 3]
after func a: 2
after func b: [1, 3]

nonlocal

指定上一级变量,如果没有就继续往上直到找到为止

类中的各种变量

案例1 -静态方法、类方法

val1是类变量,可以由类名直接调用,也可以有对象来调用;
val2是成员变量,可以由类的对象来调用,这里可以看出成员变量一定是以self.的形式给出的,因为self的含义就是代表实例对象;
val3不是成员变量,它只是函数fcn内部的局部变量;
val4和val5也都不是成员变量,虽是以self.给出,但并没有在构造函数中初始化

静态方法:
使用装饰器@staticmethod定义静态方法。
类对象和实例都可以调用静态方法

class TestClass(object):  
    val1 = 100  #有时被认为是“python静态变量”、也称类变量

    @staticmethod
    def staticFun():
        print('这是一个静态方法')
    @classmethod
    def classFun(cls,x):
        print cls.val1*x
    def __init__(self):  
        self.val2 = 200  

    def fcn(self,val = 400):  
        val3 = 300  
        self.val4 = val  
        self.val5 = 500   
    def printLocal(self):
        print self.val5
    def printStaticValue(self):
        #print val1   #错误
        print ('printStaticValue',self.val1)
        print ('printStaticValue',TestClass.val1)


inst = TestClass()  
print TestClass.val1  
print inst.val1  
print inst.val2  

print inst.printStaticValue()

TestClass.staticFun()
TestClass.classFun(66)
#print inst.val3   #错误
#print inst.val4   #错误   
#print inst.val5   #错误
#inst.printLocal() #错误
100
100
200
('printStaticValue', 100)
('printStaticValue', 100)
None
这是一个静态方法
6600

案例2-super

Foo类必须继承某个类(并且这个继承链开始于object类),否则会报错

class Foo(object):
    def hi(self):
        print 'hi,Foo'
class Foo2(Foo):
    def hi(self):
        super(Foo2, self).hi()

if __name__ == '__main__':
    foo2 = Foo2()
    foo2.hi()
hi,Foo

案例2 类变量与实例变量

python的类变量和C++的静态变量不同,区别在于python的对象使用类变量时,会进行一次内存拷贝。python中,类本身拥有自己的类变量(保存在内存),当对象第一次调用类变量时,会将当前类变量拷贝一份给这个对象,当前类变量的值是多少,这个对象拷贝得到的类变量的值就是多少;而且,通过对象来修改类变量,并不会影响其他对象的类变量的值,因为大家都有各自的副本,更不会影响类本身所拥有的那个类变量的值;只有类自己才能改变类本身拥有的类变量的值

inst1 = TestClass()  
inst2 = TestClass()  

print TestClass.val1 # 100  
print inst1.val1     # 100  

inst1.val1 = 1000      
print inst1.val1     # 1000  
print TestClass.val1 # 100  

TestClass.val1 =2000   
print inst1.val1     # 1000  
print TestClass.val1 # 2000  

'''
inst2.val1的打印结果是2000可以发现,对象的类变量并不是构造对象的时候初始化的,
而是在第一次通过对象调用该类变量的时候从类变量当前的值拷贝过来的
'''
print inst2.val1     # 2000       

inst3 = TestClass()    
print inst3.val1     # 2000 
100
100
1000
100
1000
2000
2000
2000

案例4–list变量

class Man(object):
    #直接定义的类的变量,属于类   
    #其中 gender, avg_height为基本数据类型,immutable
    #lis为列表类型,为mutable的
    gender = 'male'   
    avg_height = 1.75
    lis = ['hello', 'world']

    def __init__(self, name):
        self.name = name  #name在类的构造函数中定义,是属于对象的变量


a = Man('jason')
b = Man('tom')

#通过一个对象a访问一个变量x,变量的查找过程是这样的:
#先在对象自身的__dict__中查找是否有x,如果有则返回,否则进入对象a所属的类A的
#__dict__中进行查找

#对象a试图修改一个属于类的 immutable的变量,则python会在内存中为对象a
#新建一个gender变量,此时a就具有了属于自己的gender变量
a.gender = 'female'

#对象b试图修改一个mutable的变量,则python找到类Man的__dict__中的变量lis,
#由于lis是可以修改的,因此直接进行修改,而不会给b新生成一个变量。类Man以及类Man
#的所有对象都公用这一个lis
b.lis = ['fuck', 'world']

print a.__dict__ #属于a的变量,有 name, gender
print b.__dict__  #属于b的变量,只有name
print Man.__dict__ #属于类Man的变量,有 gender,avg_height,lis,但是不包括 name
#name是属于对象的变量

Man.t = 'test' #此时Man的变量又多了t,但是对象a和b中没有变量t。
#(这里可以看出,对象的变量和类的变量是分开的)

print a.gender  #female
print b.gender  #male

print a.lis #['fuck', 'world']
print b.lis #['fuck', 'world']

a.addr = '182.109.23.1' #给对象a定义一个变量,对象b和类Man中都不会出现(解释性语言好随性。。)
{'gender': 'female', 'name': 'jason'}
{'name': 'tom', 'lis': ['fuck', 'world']}
{'__module__': '__main__', 'gender': 'male', '__weakref__': <attribute '__weakref__' of 'Man' objects>, 'lis': ['hello', 'world'], '__dict__': <attribute '__dict__' of 'Man' objects>, 'avg_height': 1.75, '__doc__': None, '__init__': <function __init__ at 0x00000000071587B8>}
female
male
['hello', 'world']
['fuck', 'world']

参考网址

https://www.cnblogs.com/kex1n/p/5979366.html
https://www.cnblogs.com/duanv/p/5947525.html
https://www.cnblogs.com/xixi18/p/8341828.html
https://blog.csdn.net/lc_910927/article/details/38757363
https://blog.csdn.net/cadi2011/article/details/52457754
https://www.cnblogs.com/gtarcoder/p/5005897.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值