目录
基本概念
- 全局变量:在模块内、所有函数外、所有class外
- 局部变量:在函数内、在class的方法(类方法、静态方法、实例方法)内,且变量前面没有修饰
- 类变量:在class内,不在class的任何方法内
- 实例变量:在class的方法内,且使用self修饰的变量
Python中的一切都是对象
- 全局变量:属于模块对象的属性
- 局部变量:属于方法对象或函数对象的属性吗?不属于………函数对象或者方法对象必须显式的添加属性……
- 类变量:属于类对象的属性
- 实例变量:属于实例对象的属性
1、类属性与实例属性
类属性就相当与全局变量,实例对象共有的属性,实例对象的属性为实例对象自己私有。
类属性就是类对象(Tool)所拥有的属性,它被所有类对象的实例对象(实例方法)所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。
2、实例:类属性
class People(object):
name = 'Jack' #类属性(公有)
__age = 12 #类属性(私有)
p = People() #创建实例对象
print(p.name) #通过实例对象,打印类属性:name
print(People.name) #通过类对象,打印类属性:name
print(p.__age) #错误,不能在类外通过实例对象访问私有的类属性
print(People.__age) #错误,不能在类外通过类对象访问私有的类属性
#结果如下:
# Jack
# Jack
# AttributeError: 'People' object has no attribute '__age'
# AttributeError: type object 'People' has no attribute '__age'
3、实例:实例属性(对象属性)
class People(object):
address = '山东' # 类属性
def __init__(self):
self.name = 'xiaowang' # 实例属性
self.age = 20 # 实例属性
p = People() #创建实例对象
p.age = 12 # 通过实例对象调用实例属性,更改实例属性值
print(p.address) # 通过实例对象调用类属性,并打印
print(p.name) # 通过实例对象调用实例属性,并打印
print(p.age) # 通过实例对象调用实例属性,并打印
#结果:
# 山东
# xiaowang
# 12
print(People.address) # 通过类对象调用类属性,并打印
print(People.name) # 错误(程序会报错),通过类对象调用实例属性,并打印
print(People.age) # 错误(程序会报错),通过类对象调用实例属性,并打印
#结果:
# 山东
# AttributeError: type object 'People' has no attribute 'name'
# AttributeError: type object 'People' has no attribute 'age'
4、通过实例(对象)去修改类属性
class People(object):
country = 'china' # 类属性
print(People.country) #china
p = People()
print(p.country) #china
p.country = 'japan'
print(p.country) # 实例属性会屏蔽掉同名的类属性:japan
print(People.country) #china
del p.country # 删除实例属性
print(p.country) #实例属性被删除后,再调用同名称的属性,会调用类属性:china
小结
如果需要在类外修改类属性
,必须通过类对象
去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性
,这种方式修改的是实例属性
,不会影响到类属性
,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性
,除非删除了该实例属性
。
那么什么时候 使用类属性呢?
类属性就是给类对象中定义的属性。通常用来记录与这个类相关的特征。不用于记录具体对象的特征。
class Tool(object):
count = 0 # count就是一个类属性
def __init__(self,name):
self.name = name
Tool.count += 1
tool1 = Tool('斧头1')
tool2 = Tool('斧头1')
tool3 = Tool('斧头1')
tool4 = Tool('斧头1')
print(Tool.count)
这段代码中count就是一个类属性,我们可以在外部直接调用,而不经过内部__init__方法,可试着跟着敲一下,体会一二。
因此他的使用场景:记录与这个类相关的特征。不用于记录具体对象的特征的时候使用。
使用类属性和实例属性,例子
# 所有员工基类
class Employee(object):
empCount = 0
def __init__(self, name, salary) :
self.name = name
self.salary = salary
Employee.empCount += 1
# 类方法
def displayCount(self):
print ("total employee: ", Employee.empCount)
def displayEmployee(self) :
print ("name: ",self.name , ", salary: ", self.salary)
if __name__ == '__main__':
# 创建Employee类的实例对象
emp1 = Employee("丽丽", 10000)
emp1.displayCount() # total employee: 1
emp1.displayEmployee() # name: 丽丽 , salary: 10000
emp1.salary = 20000 # 修改属性 salary
print("实例属性 ", emp1.salary) # 20000
emp1.age = 25 # 添加属性 age
print(emp1.age) # 25
del emp1.age # 删除 age属性
emp1.empCount = 400
Employee.empCount = 1000
print("修改类属性:")
emp1.displayCount() # total employee: 1000
print("实例属性:", emp1.empCount) # 400
print("类属性:", Employee.empCount) # 类属性: 1000
5、【全局变量】与【局部变量】
ahead = 'HelloWorld' #ahead是全局变量
showList = [] #showList也是全局变量
def print_ahead():
print(ahead) #在该函数中没有称为ahead的局部变量,此处实际调用的是全局变量ahead
def print_other():
city = 'beijing' #city是局部变量
print(city + ahead) #局部变量 与 全局变量 拼接
def print_list():
global showList #global关键字表示引用的是全局变量showList
showList.append(1)
showList.append(2)
print(showList)
print_ahead()
print_other()
print_list()
###
# output
HelloWorld
beijingHelloWorld
[1, 2]
6、全局变量与局部变量同名
如果在print_str函数中没有使用global关键字显式引用全局变量,在print_str函数中将优先使用局部变量,而不是全局变量。
firstValue = "Hello World"
def print_str():
firstValue = "hi man"
print(firstValue) #注意:这里的firstValue调用的是局部变量firstValue,在方法中直接覆盖掉同名的全局变量firstValue
省略global关键字
当你的函数里只是读取全局变量的值,并没有对变量有任何的赋值行为(指a = XXX这种的写入)的话,可以省略global修饰全局变量。
first = 100 #first是全局变量
def my_hello():
print(first) #只是访问(读取)全局变量first的值,无需global修饰(加上global更规范)
不可省略global关键字
必须加上global修饰变量,说明是给全局变量name赋值,如果没有global修饰,只会说明你是在创建一个局部变量。
name = "王员外"
def change_name():
global name
name = "大哥大"
7、【类变量】与【实例变量】
class Person(object):
TAG = "Person" #TAG是类变量
def __init__(self, name): #self表示当前实例对象
print(Person.TAG) #类变量TAG被访问
self.personName = name #personName是实例变量
def print_name(self):
group = "BeiJing_" #group是局部变量
print(group + self.personName) # 局部变量 与 实例变量 拼接
if __name__ == "__main__":
p = Person("WangYuanWai")
p.print_name()
# output
Person
BeiJing_WangYuanWai
参考: