一、类的属性
1.类的组成由属性和方法组成,属性可以称为成员变量,方法可以称为成员函数。
2.对象的创建,创建对象的过程称之为实例化。当一个对象被创建后,包含三个方面的特性:1.对象句柄 2.属性 3.方法。
句柄:用于区分不同的对象。
对象的属性和方法与类中的成员变量和成员函数对应。
在类里面的属性和方法叫做成员变量和成员函数,在实例化后,调用这些变量和函数,就叫做对象属性和对象方法。
3.类的属性,类的属性按使用范微分为公有属性和私有属性,类的属性范围取决于属性的名称。
公有属性:在类中和类外都能调用的属性。
私有属性:不能在类外以及类以外的函数调用。
私有属性的定义方式:以__双下划线开始的成员变量就是私有属性,可以通过instance.classname_attribute方式访问。
内置属性:由系统在定义类的伤害默认添加的,有前后双下划线构成,__dict__, __module__。
比如:
class People(object):
color = 'yellow' #这就是一个公有属性,可以在类里和类外调用
__age = 30 #这就是一个私有属性,只能在类里调用。
def think(self):
self.color = "black"
print "i am a %s" % self.color
print "i am a thinker"
print(self.__age) #调用age
ren = People()
print ren.color
ren.think()
print(ren.__age)
可以看到在类里调用的__age成员变量可以调用出来,但是在类外就不行了。
如果想在外面看到的话可以这么看。但是不一般不建议这么做,在调试的时候可以用。
class People(object):
color = 'yellow'
__age = 30
def think(self):
self.color = 'black'
print(self.color)
ren = People()
print ren.color
ren.think()
print ren.__age
print ren._People__age #这就可以看到内部的属性。还是建议放在成员函数里使用。
使用内部属性这么做直接使用对象属性的方式调用。
print ren.__dict__ 是属性所以没有括号。
把公有属性分成字典的类型了。
我们不光可以使用对象来访问类的属性,还可以通过类来访问类的属性。但是只能访问公有属性。
print people.color
4.对象属性修改。
class People(object):
color = 'yellow'
__age = 30
def think(self):
self.color = 'black'
print(self.color)
ren = People()
ren.color = “白色人” #通过对象属性修改color的值
print ren.color
ren.think()
print ren._People__age
可以发现,对象属性的值得变了,但是在类中的的属性的值没有改变还是yellow。
通过类名去访问内置属性
print People.__dict__
可以发现打印出了类里的所有属性对应的值。
二、类的方法
1.类的方法的定义和定义函数一样,但是需要self作为第一个参数,这个是必须要有的。self方法就是用来区分函数和类方法的。
类的方法分为:1.公有方法 2.私有方法 3.类方法 4.静态方法
公有方法:在类中和类外都可以调用的方法。和公有属性一样
私有方法:不能被类外部调用,在方法前面加上__双下划线就是私有方法。和私有属性一样。
类方法:被classmethod()函数处理过的函数,能被类所调用,也能被对象所调用(是继承的关系)
静态方法:相当于“全局函数”,可以被类直接调用,可以被所有实例化对象共享,通过staticmethod()定义,
静态方法没有self参数。
2.可不可以通过类名调用方法呢?直接使用时不行的。必须要使用对象来调用。
People.think()
3.如果要把方法变成一个类方法我们需要使用一个函数来处理一下
使用classmethod()函数来处理一下,我们需要通过一个变量来接收一下,这样就可以访问test方法了。只要方法名字就可以了,不用加括号。
其实这种方式,我们还可以理解为动态方法,因为在调用的时候没有去加载其他方法出来。只有我们在调用的方法中,调用了其他方法才开会去加载。所以说是个动态,通过类来访问方法,加载的资源很少。
4.静态方法的定义。
如果我们直接写一个不加self的方法,是不行会报错,会当成类方法,提示你需要有一个参数。
def test():
print "test"
直接用类去调用也是不行。
我们需要一个函数去处理一下。
sm = staticmethod(test) 调用的时候也是通过这个接收的变量名去访问,
虽然看上去定义的方式差不多,但是运行机制是不一样的,静态方法调用的伤害,因为没有self这个参数,所以会把类里的所有变量都加载进内存。
但是运行速度要比动态的快。
那么静态方法如何去访问类里的成员变量呢?
如果使用self.color是不行的会报错。使用类名.属性的方式访问。
def test():
print People.color
因为self 就代表类的本身,静态方法没有self 这个参数,就使用类名来访问。
5.其实还有一种方式可以去访问类方法和静态方法。使用装饰器。
装饰器如何使用?
@staticmethod
def test():
print "this is a static method"
People.test()
装饰器就是@后面加处理的函数名,在方法的上方加装饰器,只对装饰器下面的这一个函数起作用。
这种方式就比较简便。
三、Python的内部类
1.所谓内部类,就是类的嵌套,就是在类的内部在定义类。主要目的是为了更好的抽象现实世界。
就像os模块,os.path.altsep 这就想内部类,通过OS的外部类.path内部类.去调用属性和方法:
2.定义内部类和使用内部类
第一种方式:直接使用外部类调用内部类:
class People(object):
color = 'yellow'
__age = 30
class chinese(object): #定义了一个内部类
print "i am chinese"
def think(self):
self.color = 'black'
print(self.color)
def test():
print 'Testing...'
sm = staticmethod(test)
jack = People.chinese() #第一种方式实例化内部类。
在内部类定义一个属性,如何访问呢。
name = "i am a chinese"
直接使用对象属性来访问。
但是这种方式外部类的属性和访问就调用不了了。
第二种方式:先对外部类进行实例化,然后再实例化内部类。
class People(object):
color = 'yellow'
__age = 30
class chinese(object): #定义了一个内部类
print "i am chinese"
def think(self):
self.color = 'black'
print(self.color)
def test():
print 'Testing...'
sm = staticmethod(test)
ren = People() #先实例化外部类
jack = ren.Chinese() #在实例化内部类,实例化内部类需要加上“外部类名字.内部类名字”
print jack.name
这样就是可以调用内部类的属性和方法和外部类的属性和方法了。
第三种方式:直接使用外部类加内部类加内部类属性来访问
class People(object):
color = 'yellow'
__age = 30
class chinese(object): #定义了一个内部类
print "i am chinese"
def think(self):
self.color = 'black'
print(self.color)
def test():
print 'Testing...'
sm = staticmethod(test)
print People.Chinese.name #使用类的方法来访问。
print People.Chinese().name #使用对象的方法来访问,其实这就是第一种方式的实例化内部类了。
3.类的内置方法,又称魔术方法
1.__str__(self)内置方法
先看实例化后对象的返回结果。
class People(object):
color = 'yellow'
__age = 30
class Chinese(object):
name = "i am a chinese"
def __str__(self):
return "This is a People object"
def think(self):
self.color = 'black'
print(self.color)
# print(self.__age)
@classmethod
def test1(self):
print("this is a class method")
@staticmethod
def test():
print "this is static method"
ren = People()
print ren
使用__str__方法后的结果
可以看到输出变了。而且不用去调用__str__内置方法。在运行的时候就直接加载了。__str__内置方法只能用给return ,不能用print。
2.构造函数和析构函数
构造函数:用于初始化类的内部状态,Python中提供的构造函数是__init__()
析构函数:用于释放对象占用的资源,Python中提供析构函数的是__del__()
首先来看下构造函数。
class People(object):
color = 'yellow'
__age = 30
class Chinese(object):
name = "i am a chinese"
def __str__(self):
return "This is a People object"
def __init__(self):
self.color = 'red'
def think(self):
self.color = 'black'
print(self.color)
# print(self.__age)
@classmethod
def test1(self):
print("this is a class method")
@staticmethod
def test():
print "this is static method"
ren = People()
print ren.color #通过对象访问就变成了red
print People.color #通过类属性访问还是没变。
这个函数也是自动执行,当我们实例化类的时候就会自动执行。
通常我们用这个构造方法来修改参数。通过对象访问的属性会根据我们传的值不同属性会改变。而根据类的这种方式是不变的。
构造函数可以放属性和方法,而且不需要调用就可以加载出来。
class People(object):
color = 'yellow'
__age = 30
class Chinese(object):
name = "i am a chinese"
def __str__(self):
return "This is a People object"
def __init__(self,c='green'):
self.color = c
self.think()
def think(self):
self.color = 'black'
print(self.color)
# print(self.__age)
@classmethod
def test1(self):
print("this is a class method")
@staticmethod
def test():
print "this is static method"
ren = People()
print ren.color
print People.color
析构函数:在脚本执行的最后来执行__del__内置方法。用于结束占用的资源
class People(object):
color = 'yellow'
__age = 30
class Chinese(object):
name = "i am a chinese"
def __str__(self):
return "This is a People object"
def __init__(self):
print "init...."
self.fd = open('1.txt') #打开一个文件
self.think()
def think(self):
self.color = 'black'
print(self.color)
@classmethod
def test1(self):
print("this is a class method")
@staticmethod
def test():
print "this is static method"
def __del__(self):
print "del...."
self.fd.close() #关闭回收
ren = People()
print ren.color
print People.color
print "Main end"
可以看到del这个内置方法是在脚本结束后才执行的。
3.其实在Python中del这个内置方法是可选的。如果不提供,Python会在后台提供默认的析构函数。
Python有一个垃圾回收机制,使用gc模块释放不在使用的对象。采用引用计数的算法方式来处理回收。可以使用gc.collect()方法一次性收集所有待处理的对象。