python中變量

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





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章