面向对象基础二

1 特殊方法

参考资料:
Python 特殊方法一览 来源:优快云
Python的特殊方法 来源:优快云

特殊方法: 特殊方法也称魔法方法,形如__xxx__() 这种形式(如:__ str__)可以在类中定义,他们无需程序员调用,在特定的时候会自动调用
常见特殊方法:(以下图片来自上述博文:Python 特殊方法一览
和运算符无关的特殊方法
  和运算符相关的特殊方法

2 构造函数和构析函数

参考资料:
Python面向对象编程-封装

  • 构造函数: python中的构造函数是__init__(),用于初始化类对象的初始化,__ init__()方法是可选的,如果不提供,python会给出一个默认的__init__()方法。
  • 构析函数: python中的析构函数是__del__(),用于释放对象占用的资源。析构函数也是可选的,如果不提供,则python会提供默认的析构函数。如果要显示调用析构函数,可以使用del关键字。

3 封装

参考资料:
第十二讲—面向对象二 来源:优快云
Python面向对象编程-封装 来源:优快云 (强烈推荐)

  • 封装: 封装是面向对象的三大特性之一,是指隐藏对象中一些不希望被外部访问到的属性或方法
  • 封装 封装是指隐藏对象中一些不希望被外部访问到的属性或者方法,达到增强数据安全,使得属性不能随意更改
  • 优点:
    • 隐藏了属性名,调用类时就无法随意修改对象中的属性
    • 增加了getter()和setter()方法,很好的控制了属性是否是只读类型
    • 如果希望属性只读,则可以直接去掉setter方法
    • 如果希望属性不能被外部访问,则可以直接去掉getter方法
    • 使用getter方法和setter方法获取和设置属性的时候,可以在读取属性和修改属性的时候做一些其他的操作
  • 无法随意修改对象属性的方法: 隐藏属性名,即在对象的属性前使用双下划线(形如:__ xxx),双下划线开头的属性就是对象的隐藏属性,只能在类的内部访问,无法通过对象访问
  • 访问隐藏属性方法:_ 类名__ 属性名
    一般情况下,通过_ 类名__ 属性名的方法依然可以在外部访问属性,所以此方式一般不用,只将一些私有属性以_ 开头,且没有特殊情况,尽量不修改私有属性
  • 类的成员变量和对象的成员变量: 类的成员变量定义在类中,和类的成员函数在同一缩进等级。而对象的成员变量定义在__init__(self)成员函数中,和__init__(self)函数下的变量和语句在同一等级。通俗地讲,类的成员变量属于类,共类的所有对象和类本身所共有,也就是说所有的类的对象和类只有一份这样的变量。而对象的成员变量属于类的对象本身,每个对象都有一份,而且各个对象之间互不影响。
  • 属性分类:
    • 类属性: 类属性是指在类中直接定义的属性,分为私有类属性(形如:__ xxx)和普通类属性,类属性只能通过类对象来修改,无法通过实例对象修改
    • 实例属性(对象属性): 实例属性是指通过实例对象添加的属性,只能通过对象来访问或者修改,类对象无法访问以及修改
  • 方法分类:
    • 实例方法: 在类中定义,以self为第一个参数的方法都是实例方法,可以通过实例和类调用,在通过实例调用时会将调用对象以self自动传入,当通过类调用时,不会自动传递self,我们必须手动传入self
    • 类方法: 指在类中用@classmethod 修饰的方法,类方法第一个参数是cls,也会自动被传递,cls就是当前的类对象,类方法可以通过实例调用,也可以通过类调用
    • 静态方法: 指在类中用@staticmethod修饰的方法,它不需要指定任何的默认方法,可以通过类和实例调用(静态方法基本是一个和当前类无关的方法,只是一个保存在当前类的函数,一般都是一些工具方法,和当前类无关)
  • 公有成员变量和私有成员变量: python中用成员变量的名字来区分是共有成员变量或者是私有成员变量。python中,以两个下划线‘__’开头的变量都是私有成员变量,而其余的变量都属于公有成员变量。其中,私有的成员变量只能在类的内部访问,而共有的公有的成员变量可以在类的外部进行访问。

注:此代码为复制代码,强烈推荐原文,地址为:Python面向对象编程-封装

#实例1 
class Person():
    # 人口数和土地面积属于人类共享的信息,设置为类公有变量
    population = 0
    earth = 10000
    # 诺亚方舟能再多少人,自然不应该让每个人都知道,设置为类私有变量
    __noahCapacity = 10

    def __init__(self, name, age, salary):
        # 名字就是用来让大家知道的,每个人不一样,所以这里设置为对象的公有变量
        self.name = name
        # 年龄也类似,设置为对象的公有变量
        self.age = age
        # 薪水当然属于每个人都很敏感的啦,设置为对象的私有变量
        self.__salary = salary

    def __privateFun(self):
        print("这是私有成员函数的输出")

    # 在类的内部访问对象的公有和私有变量
    def printInstance(self):
        print("*" * 50, "公有成员函数被调用", "*" * 50)
        print("在类内部可以通过self访问对象的公有和私有变量:")
        print("name: %s age: %d salary:%d" % (self.name, self.age, self.__salary))
        print("通过类内部的成员函数,在类的内部调用私有成员函数:")

        self.__privateFun()
        print("*" * 120)


    # 在类的内部访问类的公有变量和私有变量
    def printClass(self):
        print("-" * 50, "公有成员函数被调用", "-" * 50)
        print("在类内部可以通过self访问类的公有和私有变量:")
        print("population: %d earth: %d NoahCapacity: %d" % (self.population, self.earth, self.__noahCapacity))
        print("在类内部也可以通过类名访问类的公有和私有变量:")
        print("population: %d earth: %d NoahCapacity: %d" % (Person.population, Person.earth, Person.__noahCapacity))
        print("-" * 120)



if __name__ == "__main__":
    tom = Person("Tom", 24, 9000)

    print("在类外部访问属性操作", "|" * 100)
    print("在类外部可以通过对象名访问类的公有变量:")
    print("population: %d earth: %d" % (tom.population, tom.earth))
    print("在类外部也可以通过对象名用特殊方法访问类的私有变量(仅用于调试):")
    print("NoahCapacity: %d" % tom._Person__noahCapacity)
    print("在类外部可以通过对象名访问对象的公有变量:")
    print("name: %s age: %d" % (tom.name, tom.age))
    print("在类外部也可以通过类名访问类的公有变量:")
    print("population: %d earth: %d" % (Person.population, Person.earth))
    print("|" * 120)
    print("")
    print("在类的外部调用类的成员函数", "|" * 100)
    print("在类外通过对象名调用类的公有成员函数")

    tom.printInstance()
    tom.printClass()
    print("|" * 120)

运行结果:
在这里插入图片描述
以上代码结论总结为:
在这里插入图片描述

4 property装饰器

  • property装饰器作用: 使用@property装饰器创建只读属性,@property也可以将方法伪装成同名称的只读属性,这样便可以与所定义的属性配合使用,防止属性被修改
    示例原文链接:(python)面向对象三大特性之(封装)
#面向对象 @property示例一
class Pepple:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height
    @property
    def bmi(self):
        return self.weight/(self.height*self.height)
monicx=Pepple('monicx',63,1.78)
zzzz=Pepple('ZZZZ',55,1.58)
#首先需要明确,bmi是算出的,不是一个固定的值,我们必须编写一个功能,每次调用都会立即计算一个值
# monicx.bmi=monicx.weight/(monicx.height*monicx.height)
# print(monicx.bmi)
# print(zzzz.bmi())
# print(monicx.bmi())
#bmi不是一个功能虽一个特征,使用函数不太好,最好是一个变量属性为好。
#于是我们需要为bmi这个函数添加装饰器(property),将其伪装成一个数据属性
print(zzzz.bmi)
#此时调用zzzz.bim本质就触发函数bmi执行,从而拿到其返回值。
print(monicx.bmi)
'''
运行结果:
22.031725684986377
19.883853048857468
'''
#----------------------------------------------------------------
#面向对象 @property示例二
class People:
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):  # obj.name
        print('访问用户名。。。')
        return self.__name

    # 修改用户名
    @name.setter  # obj.name='monicx'
    def name(self, x):
        if type(x) is not str:
            raise TypeError('名字必须是str类型')
        self.__name = x

    # 删除用户名
    @name.deleter
    def name(self):
        print('可以在这里加上判断用户的管理权限。是否让其删除')
        del self.__name


obj = People('egon')
print(obj.name)
del obj.name
# obj.name
'''
运行结果:
访问用户名。。。
egon
可以在这里加上判断用户的管理权限。是否让其删除
'''
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值