类的属性、方法

1.类的属性

创建对象的过程称之为实例化;当一个对象被创建后,包含三个方面的特性:对象句柄、属性和方法。
句柄用于区分不同的对象
对象的属性和方法与类中的成员变量和成员函数对应
obj = MyClass() //创建类的一个实例(对象)
通过对象来调用方法和属性

  • 类的属性按使用范围分为公有属性和私有属性,类的属性范围取决于属性的名称。
  • 公有属性:在类中和类外都能调用的属性。
    • 私有属性:不能在类外及被类以外的函数调用。
      定义方式:以”__”双下划线开始的成员变量就是私有属性
      可以通过instance._classname__attribute方式访问。第一个下划线只有一个,第二个下划线是2个
#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:
class People(object):
    color = 'yellow'    # 公有属性
    __age = 30      # 定义私有属性
    def think(self):
        self.color = 'black'    # 调用公有属性
        print self.__age        # 调用私有属性
        print "I am a %s" % self.color
        print "I am a thinker"

ren = People()
print ren.color
ren.think()
print ren.__age
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
yellow
30
I am a black
I am a thinker
Traceback (most recent call last):
  File "C:/Users/chawn/PycharmProjects/pyex/180108/1.py", line 17, in <module>
    print ren.__age
AttributeError: 'People' object has no attribute '__age'

私有属性在外部调用报错AttributeError: 'People' object has no attribute '__age'。
正确写法:print ren._People__age

  • 内置属性:由系统在定义类的时候默认添加的,由前后双下划线构成,_dict_, _module_
#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:
class People(object):
    color = 'yellow'    # 公有属性
    __age = 30      # 定义私有属性
    def think(self):
        self.color = 'black'    # 调用公有属性
        print self.__age        # 调用私有属性
        print "I am a %s" % self.color
        print "I am a thinker"

ren = People()
print ren.color
ren.think()
print ren.__dict__    #输出内置属性
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
yellow
30
I am a black
I am a thinker
{'color': 'black'}  #以字典输出

通过类来调用内置属性:

#!/usr/bin/python
# -*- coding:utf8 -*-
# author: chawn
# date:
class People(object):
    color = 'yellow'    # 公有属性
    __age = 30      # 定义私有属性
    def think(self):
        self.color = 'black'    # 调用公有属性
        print self.__age        # 调用私有属性
        print "I am a %s" % self.color
        print "I am a thinker"

ren = People()
ren.color = '白色'    #给对象的属性赋值
print ren.color
ren.think()
print ren.__dict__
print '*' *30    # *重复30次
print People.color  # 通过类调用属性color
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
白色  #输出对象的属性
30
I am a black
I am a thinker
{'color': 'black'}
******************************
yellow  # 类的属性输出
{'__module__': '__main__', 'color': 'yellow', '__doc__': None, '__dict__': <attribute '__dict__' of 'People' objects>, '_People__age': 30, '__weakref__': <attribute '__weakref__' of 'People' objects>, 'think': <function think at 0x03384930>}  # 类的内置属性

2.类的方法

  • 方法的定义和函数一样,但是需要self作为第一个参数。
    类方法为:

    • 公有方法
    • 私有方法
    • 类方法
    • 静态方法
  • 公有方法:在类中和类外都能调用的方法。

  • 私有方法:不能被类的外部调用,在方法前面加上”__”双下划线就是私有方法。

  • self参数
    用于区分函数和类的方法(必须有一个self),self参数表示执行对象本身。

class People(object):
    color = 'yellow'  
    def think(self):    # 公有方法
        print "I am a thinker"
    def f(self):
        self.think()  # 内部调用公有方法
ren = People()
ren.think()  
ren.f()  #外部调用公有方法
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
I am a thinker
I am a thinker

看下私有方法:

class People(object):
    color = 'yellow'    
    def think(self):    
        print "I am a thinker"
    def __f(self):  # 私有方法
        self.think()    #内部调用公有方法
ren = People()
ren.think()
ren.__f()   #外部不可调用私有方法
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
I am a thinker
Traceback (most recent call last):
  File "C:/Users/chawn/PycharmProjects/pyex/180108/1.py", line 13, in <module>
    ren.__f()
AttributeError: 'People' object has no attribute '__f'
  • 类方法:被classmethod()函数处理过的函数,能被类所调用,也能被对象所调用(是继承的关系)
  • 静态方法:相当于”全局函数”,可以被类直接调用,可以被所有实例化对象共享,通过staticmethod()定义,静态方法没有”self”参数。
    装饰器:
    • @classmethod
    • @staticmethod
class People(object):
    color = 'yellow'
    def think(self):
        print "I am a thinker"
    def __f(self):  # 私有方法
        self.think()    #内部调用公有方法
    def test(self):
        print 'ok'
    cm = classmethod(test)  #处理一下方法

ren = People()
People.cm()  #通过类访问被处理过得方法,没被处理的不调用
People.think()
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
ok
 File "C:/Users/chawn/PycharmProjects/pyex/180108/1.py", line 17, in <module>
    People.think()
TypeError: unbound method think() must be called with People instance as first argument (got nothing instead)
# think方法没有被classmethod处理,所以类不能调用

静态方法()里为空,不能直接被对象或者类调用,要先用staticmethod处理。而且正因为没有self参数,所以不能调用其他方法,只能调用属性。相比之下,作用很静态。

class People(object):
    color = 'yellow'
    def think(self):
        print "I am a thinker"
    def __f(self):  # 私有方法
        self.think()    #内部调用公有方法
    def test(): # 静态方法
        print 'ok'

ren = People()
People.cm()

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
Traceback (most recent call last):
  File "C:/Users/chawn/PycharmProjects/pyex/180108/1.py", line 15, in <module>
    People.cm()
AttributeError: type object 'People' has no attribute 'cm'
class People(object):
    color = 'yellow'
    def think(self):
        print "I am a thinker"
    def __f(self):  # 私有方法
        self.think()    #内部调用公有方法
    def test(): # 静态方法
        print 'ok'
    cm = staticmethod(test)
ren = People()
People.cm()

C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
ok

装饰器,有装饰器之后,类可以直接访问:

class People(object):
    color = 'yellow'
    def think(self):
        print "I am a thinker"
    def __f(self):  # 私有方法
        self.think()    #内部调用公有方法

    @classmethod
    def test(self): # 动态方法
        print 'haha'

    @staticmethod
    def test1():    #静态方法
        print 'ok'

ren = People()
People.test()
People.test1()
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
haha
ok

3. 内部类

  • 所谓内部类,就是在类的内部定义的类,主要目的是为了更好的抽象现实世界。
  • 例子:
    汽车是个类,汽车的底盘,轮胎也可以抽象为类,将其定义到汽车类中,则形成内部类,更好的描述汽车类,因为底盘、轮胎是汽车的一部分。
  • 方法1:直接使用外部类调用内部类
    object_name = outclass_name.inclass_name()
class People(object):
    color = 'yellow'
    class Chinese(object):
        name = '内部类'
    def think(self):
        print "I am a thinker"
ren = People.Chinese()
print ren.name
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
内部类
  • 方法2:先对外部类进行实例化,然后再实例化内部类
    out_name = outclass_name()
    in_name = out_name.inclass_name()
    in_name.method()
class People(object):
    color = 'yellow'
    class Chinese(object):
        name = '内部类'
    def think(self):
        print "I am a thinker"
ren = People()  # 在People里取对象
tom = ren.Chinese()  # 在Chinese再取一个对象
print tom.name

也可换成:

class People(object):
    color = 'yellow'
    class Chinese(object):
        name = '内部类'
    def think(self):
        print "I am a thinker"
# ren = People()
# tom = ren.Chinese()
# print tom.name
print People.Chinese.name
C:\Users\chawn\PycharmProjects\pyex\venv\Scripts\python.exe C:/Users/chawn/PycharmProjects/pyex/180108/1.py
内部类

魔术方法:

  • _str_(self)
  • 构造函数与析构函数
    • 构造函数:
      用于初始化类的内部状态,Python提供的构造函数是_init_();
      _init_()方法是可选的,如果不提供,Python会给出一个默认的_init_方法
    • 析构函数:
      用于释放对象占用的资源,Python提供的析构函数是_del_();
      _del_()也是可选的,如果不提供,则Python会在后台提供默认析构函数
class People(object):
    color = 'yellow'
    class Chinese(object):
        name = '内部类'
    def think(self):
        print "I am a thinker"
    def __str__(self):
        return '这是People类'  # 只能用return,不能用print
    def __init__(self):
        self.color = 'black'
    def __del__(self):
        print 'del..'
ren = People()
print ren
print ren.color
print People.color

_del_(self)在程序最后执行,比如程序执行完关闭某文件。不手动关闭的话,Python也会自动回收。

  • Python采用垃圾回收机制来清理不再使用的对象;python提供gc模块释放不再使用的对象。
  • Python采用”引用计数”的算法方式来处理回收,即:当某个对象在其作用域内不再被其他对象引用的时候,python就自动清除对象;
  • gc模块的collect()可以一次性收集所有待处理的对象(gc.collect)

推荐阅读更多精彩内容

  • 1.1面向对象 面向对象(object-oriented ;简称: OO)至今还没有统一的概念 我这里把它定义为:...
    TENG书阅读 424评论 0 0
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,226评论 0 9
  • 仿佛所有的感觉都回到原点,一切都陌生,让人好奇。 一万七千字,打印出来三十二页纸的论文初稿,装订在透明的书皮里,新...
    精装荷兰豆阅读 48评论 0 0
  • 看了清宫医案,光绪的遗精病很严重,当时最高水平的御医也无能为力。 从光绪的经历看,从小情致压抑,长大以后被慈禧囚禁...
    介普散人阅读 663评论 0 0