实例属性&类属性
类是模板,而实例则是根据类创建的对象。实例属性是绑定在一个实例上的,各自独立,不会影响到其他实例,但如果类上绑定一个属性,则所有实例都可以访问类的属性,并且所有实例访问的类的属性都是同一个,如下示例:
class Person(object):
#类属性
address = 'earth'
def __init__(self, name, gender, age):
#实例属性
self.name = name
self.gender = gender
self.age = age
p1 = Person('zhangsan', 'male', 20)
print(p1.name)
print(p1.gender)
print(p1.age)
print(Person.address)
print(p1.address)
print('********给实例设置address属性********')
p1.address = 'China'
print(Person.address)
print(p1.address)
执行该代码结果如下:
zhangsan
male
20
earth
earth
********给实例设置address属性********
earth
China
如上代码可知,当在实例上给类属性赋值时,实际上是给这个实例绑定了同名的属性而已,并不会影响类属性和其他实例。由此可见使用实例访问一个属性时优先查找实例上是否有该属性,如果没有再去类上查找(当实例属性和类属性重名时,实例属性优先级高)。
实例方法&类方法&静态方法
class Demo(object):
def __init__(self):
super(Demo, self).__init__()
#实例方法有隐含的self参数,代表实例对象
def instanceMethod(self):
return 'instance method'
#用@classmethod装饰器来定义类方法,类方法有隐含的cls参数,代表类本身
@classmethod
def classMethod(cls):
return 'class method'
#用@staticmethod装饰器来定义静态方法,静态方法没有隐含的self或cls参数
@staticmethod
def staticMethod():
return 'static method'
demo = Demo()
#实例方法只能用实例访问
print(demo.instanceMethod())
#类方法和静态方法既可以用类访问,可以用实例访问
#类方法和静态方法的区别在于隐含参数的传递上
print(Demo.classMethod())
print(demo.classMethod())
print(Demo.staticMethod())
print(demo.staticMethod())
类成员的访问控制
Python中类的成员默认都是公开的(public),在Python中没有类似public、private等关键词来修饰类的成员。在Python中定义私有成员只需要在变量名或函数名前加上两个下划线,那么这个函数或变量就变成私有的了。在外部使用原来的私有成员的名字时,会提示找不到。但这种方式只是一种约定的方式,如果想在外部调用,还是可以调用的,具体看如下代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Demo(object):
"""docstring for Demo"""
def __init__(self):
super(Demo, self).__init__()
self.__message = 'Hello World'
def __getMessage(self):
return self.__message
if __name__ == '__main__':
demo = Demo()
#直接调用会报错:AttributeError: 'Demo' object has no attribute '__getMessage'
#print(demo.__getMessage())
#我们来看一下demo模块都有哪些成员
print(dir(demo))
"""
可以看到原来Python使用一种name mangling(名称修饰)技术,将__membername替换成_classname__membername,
['_Demo__getMessage', '_Demo__message', ...]
"""
#我们使用修饰后的名字就可以成功调用
print(demo._Demo__message)
print(demo._Demo__getMessage())
所以Python的私有成员并不是真正意义上的私有,在类外部也可以调用。
魔术方法(Magic Method)
Python的魔术方法有如下几个特点:
- 定义在class中
- 不需要直接调用
- Python的某些函数或操作符会调用对应的特殊方法
我们来看一个示例,如果需要把一个类的实例变为str,就需要实现特殊方法__str__(),如下所示:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __str__(self):
return 'person: %s, %s' % (self.name, self.gender)
p = Person('zhangsan', 'male')
print(p)
#输出 person: zhangsan, male
还有很多其他的魔术函数,如果要一个实例表现得像一个list,可以用len()函数获取个数,需要实现__len__()方法。如果要把一个实例变为一个可调用的对象,需要实现__call__()方法等等。
get/set方法
使用 get/set 方法来封装对一个属性的访问在很多面向对象编程的语言中都很常见,如下所示:
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
def get_score(self):
return self.__score
def set_score(self, score):
self.__score = score
s = Student('zhangsan', 90)
s.set_score(100)
print(s.get_score())
# 输出100
但这样写起来有些麻烦,Python里提供了@property装饰器,可以把方法“装饰”成属性调用。如下所示:
class Student(object):
def __init__(self, name, score):
self.name = name
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, score):
self.__score = score
s = Student('zhangsan', 90)
s.score = 100
print(s.score)
# 输出100
注意: 第一个score(self)是get方法,用@property装饰,第二个score(self, score)是set方法,用@score.setter装饰,@score.setter是前一个@property装饰后的副产品。这样就可以像使用属性一样设置score了。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!