一、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類實例都可以調用。