澳门在线威尼斯官方 > 电脑操作 > 面向对象之,类的属性

原标题:面向对象之,类的属性

浏览次数:116 时间:2019-11-10

 

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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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>}  # 类的内置属性

在线编程
在线预览:http://github.lesschina.com/python/base/oop/1.封装.html

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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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:UserschawnPycharmProjectspyexvenvScriptspython.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.1创建一个类¶

In [1]:

# 类名首字母大写
class Student(object):
    """创建一个学生类"""
    # 没有属性定义,直接使用即可
    # 定义一个方法,方法里面必须有self(相当于C#的this)
    def show(self):
        print("name:%s age:%d"%(self.name,self.age))

In [2]:

# 实例化一个张三
zhangsan=Student()
# 给name,age属性赋值
zhangsan.name="张三"
zhangsan.age=22
# 调用show方法
zhangsan.show()

 

name:张三 age:22

In [3]:

# 打印一下类和类的实例
print(Student)
print(zhangsan) #张三实例的内存地址:0x7fb6e8502d30

 

<class '__main__.Student'>
<__main__.Student object at 0x7fe961195b70>

 

和静态语言不同,Python允许对实例变量绑定任何数据 ==> 对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称可能都不同

说的比较抽象,举个例子就明了了:

In [4]:

xiaoming=Student("小明",22)
xiaoming.mmd="mmd"
print(xiaoming.mmd)

# 小明和小潘都是Student类,但是小明有的mmd属性,小潘却没有
xiaopan=Student("小潘",22)
print(xiaopan.mmd)

 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-500940527165> in <module>()
----> 1xiaoming=Student("小明",22)
      2 xiaoming.mmd="mmd"
      3 print(xiaoming.mmd)
      4 
      5 # 小明和小潘都是Student类,但是小明有的mmd属性,小潘却没有

TypeError: object() takes no parameters

 

1.2使用__init__初始化赋值¶

创建对象后,python解释器默认调用__init__方法,对必要字段进行初始化赋值

需要注意的是:__init__并不是C#中的构造函数,__new__ (后面会说) + __init__ 等价于构造函数

第一个参数和类的其他方法一样,都是self(相当于C#里面的this,表示创建的实例本身)调用的时候直接忽略它

In [5]:

class Student(object):
    # 初始化赋值
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print("name:%s age:%d"%(self.name,self.age))

In [6]:

# 有了__init__方法,在创建实例的时候,就不能传入空的参数了
lisi=Student()

 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-1ba88e24910b> in <module>()
      1 # 有了__init__方法,在创建实例的时候,就不能传入空的参数了
----> 2lisi=Student()

TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'

In [7]:

# 创建一个正确的实例
xiaowang=Student("小王",22)
xiaowang.show()

 

name:小王 age:22

 

1.3使用魔法方法__str__¶

在print(类名)的时候自定义输出

这个有点像C#类里面重写ToString,eg:

public override string ToString()
{
    return "Name:" + this.Name + " Age:" + this.Age;
}

In [8]:

# Python的__str__()方法
class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # self别忘记写了,return也别忘了
    def __str__(self):
        return "姓名:%s,年龄:%s" % (self.name, self.age)

In [9]:

lisi = Student("李四", 22)
print(lisi) #现在打印就是你DIV的输出了

 

姓名:李四,年龄:22

 

本文由澳门在线威尼斯官方发布于电脑操作,转载请注明出处:面向对象之,类的属性

关键词:

上一篇:没有了

下一篇:没有了