一、python中变量划分:
1、全局变量: 在模块内,所有class和def方法中。 2、局部变量:在模块内,在def方法内; 3、静态变量:在模块内,class内,但不在def方法中; 4、实例变量:在模块内,在class和def方法中,使用self修饰。
二、实例分析
# --*-- coding: utf8 --*-- # 全局变量 name = 'Lily' job = 'dancer' gender = 'male' class people: # 静态变量 city = "shenzhen" def __init__(self): # 实例变量,仅供当前类实例调用 self.age = 12 def changejob(self, jobb, nameb): # 方法内修改全局变量 global job, name job = jobb name = nameb def showinfo(self): # gender 为局部变量,仅供当前方法使用 gender = 'Female' print("%s is a %s. She is %d years old. She is a %s, she is in %s " % (name, gender,self.age, job, self.city)) if __name__ == "__main__": p1 = people() p1.showinfo() people().changejob("singer", "Lucy") p2 = people() p2.showinfo()
Execute Result:
Lily is a Female. She is 12 years old. She is a dancer, she is in shenzhen Lucy is a Female. She is 12 years old. She is a singer, she is in shenzhen
解析:
- 全局变量,在模块内可以直接被调用,不需要添加任何前缀;
- 局部变量,在方法showinfo中,gender为局部变量,优先级高于全局变量,so执行结果为Female;
- 实例变量,在__init__方法中,定义的实例变量,仅供当前类的这个实例使用(如果其他类继承该类,并调用该构造方法,也可以使用),使用时需要使用前缀self(self代表类的实例);
- 静态变量:在class内,方法外的city是实例变量,使用时需要self前缀。
实例变量,在类继承中使用:
class people: def __init__(self,age=12, name='Tom', weight=None): self.age = age self.name = name self.weight = weight def speak(self): print("%s 说: 我 %d 岁" % (self.name, self.age)) class student(people): def __init__(self, age, name,job): # 如下2种方式,都可以调用父类的构造方法 super().__init__(age, name) #people.__init__(self, age, name, weight=None) self.job = job def speak(self): print(self.age, self.name) print("% is a %s, she is %d" % (self.name, self.job, self.age)) if __name__ == "__main__": s = student(22, 'Lily','dancer') s.speak()
Execute Result:
Lily is a dancer, she is 22
在使用unittest测试框架中,发现一个问题:
import unittest class people(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def test_01_info(self): self.age = 22 self.job = 'dancer' people.name = "Lily" people.test_01_list = dir(self) def test_02_speak(self): people.test_02_list = dir(self) print("%s is a %s, she is %d" % (self.name, self.job, self.age)) def test_03_speak(self): print(self.test_01_list) print(self.test_02_list) print( list(set(self.test_01_list).difference(set(self.test_02_list)))) if __name__ == "__main__": unittest.main(verbosity=2)
Execute Result:
test_01_info (__main__.people) ... ok test_02_speak (__main__.people) ... ERROR test_03_speak (__main__.people) ... ok ====================================================================== ERROR: test_02_speak (__main__.people) ---------------------------------------------------------------------- Traceback (most recent call last): File "D:/Richard/python/learn/Sock/test1.py", line 20, in test_02_speak print("%s is a %s, she is %d" % (self.name, self.job, self.age)) AttributeError: 'people' object has no attribute 'job' ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (errors=1) ['__call__', ... , name, age, job] ['__call__', ... , name] ['job', 'age']
解析(暂时猜测,还不能肯定是正确的):
- 在class的def方法内,self.age定义了实例1的实例属性,在test_01_info(self)方法完成后,该实例释放,实例相关属性释放,在test_02_speak(self)中,新创建的实例使用self.age时,会报错,提示:类没有age这个属性。
- 在在class的def方法内,people.name直接修改类非类某个实例的属性,people类实例都可以调用。