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类实例都可以调用。





猜你喜欢

转载自blog.csdn.net/freezing12/article/details/80496504