python-封装_隐藏属性_property特性_类中函数的定义

面向对象编程

1. 封装

1.封装

封装等级 :

1. 私有: 在类的内部可以访问 , 在类外不可以

2. 公有: 在类的内部可以访问 , 在类外也可以访问

2. 封装成员

在封装的基础上 , 可以将装到对象或者类中的属性给隐藏起来

1. 成员属性

2. 成员方法

调用成员:

1. 对象.成员属性

2. 对象.成员方法

3. 绑定方法

1. 绑定到对象: 对象调用时 , 系统默认传递该对象 , 作为一个参数传递到当前方法中

2. 绑定到类: 对象或者类调用方法时 , 系统默认传递该类 , 作为一个参数传递到当前方法中

4. 注意

1. 定义类或者初始化对象时 , 在属性前加 __ , 就会将该属性隐藏起来

2. 但是该隐藏其实只是一种变形 _类名__属性名

3. 该变形操作是在类定义阶段扫描语法是发生的变形 , 类定义之后添加的 __开头的属性不会发生变形

4. 该隐藏是对外不对内

5. 在继承中 , 父类如果不想让子类覆盖自己的方法 , 可以将方法定义为私有的

# 例1
class Student:
    # 私有成员属性
    __school = "oldboy" # _Student__school = "oldboy"
    
    def __init__(obj,x,y,z):
        obj.__name = x # obj._Student__name = x
        obj.age = y
        obj.gender = z
    
    # 私有成员方法
    def __choose(self): # obj._Student__choose
        print("%s 正在选课" %self.name)

# 实例化对象        
stu_obj1 = Student("冯疯子",18,"female")
stu_obj1.__x = 111
# __dict__ 获取类对象中的成员
print(stu_obj1.__dict__)
print(stu_obj1.__x)

print(stu_obj1.__dict__)
print(stu_obj1._Student__name)

print(Student.__dict__)
print(Student._Student__school)
print(stu_obj1._Student__school)
5. 对象操作
class MyCar():
	# 公有成员属性
	color = "屎黄色"
	logo =  "中国吉利汽车"
	# 私有成员属性
	__price = "2000万"
	
	# 公有成员方法
	def run(self):
		print("小车会跑,百公里0.01秒,颜色{}".format(self.color)) # self <=> obj 
	# 私有成员方法
	def __info(self):
		print("车主信息是保密的,传说是京城有名的富二代")
		
# 实例化对象(类的实例化)
obj = MyCar()

# 一.实例化的对象访问公有成员属性和方法
# 访问属性
print(obj.color)
# obj.__price error  # 私有成员属性不能够在类外调用
		
# 访问方法
obj.run()
# obj.__info() error  # 私有成员方法不能够在类外调用
	
# 二.实例化的对象动态添加公有成员属性和方法
# 1. 在类外动态添加成员属性
obj.logo = "五菱宏光"
print(obj.logo)
# __dict__ 是获取类对象中的成员
print(obj.__dict__)

# 2. 在类外动态添加成员方法
# 2.1 无参方法
def dahuangfeng():
    print("变形!我是大黄蜂~")
stu_obj1.dahuangfeng = dahuangfeng
stu_obj1.dahuangfeng()
# 2.2 有参方法
# 基础版
def qingtianzhu(name):
    print("请叫我一柱擎天,简称{}".format(name))
stu_obj1.qingtianzhu = qingtianzhu
stu_obj1.qingtianzhu(obj,"擎天柱")

# 升级版
def qingtianzhu(name):
    print("请叫我一柱擎天,简称{},颜色是{}".format(name,obj.color))
stu_obj1.qingtianzhu = qingtianzhu
stu_obj1.qingtianzhu(obj,"擎天柱")

# 究极版
# 即使使用类外动态创建的方法,也让系统传递obj对象本身
# 在类外调用自定义方法时,系统不会自动传递obj对象参数
import types
def qingtianzhu(obj,name):
    print("请我叫我一柱擎天,简称{},颜色是{}".format(name,obj.color))
# MethodType(方法,对象) 把哪个方法和哪个对象绑定到一起,形成绑定方法
obj.qingtianzhu = type.MethodType(qingtianzhu,obj)
obj.qingtianzhu("擎天柱")

# lambda 表达式
obj.weizhentian = lambda : print("我是威震天~")
obj.weizhentian()
6. 类操作

类调用方式

类.成员属性

类.成员方法

类中的无参方法只能是类来调用

类和对象之间的区别

对象可以调用类中的成员属性和方法 , 类不能调用对象中的成员

类中的成员属性和方法归属于类本身 , 对象可以使用 , 但是没有修改和删除的权利

对象在调用相应成员是 , 先看看自己有没有

如果有 , 调用自己的

如果没有 , 调用类中的成员

如果类中成员也没有 , 直接报错

class MyCar():
    # 公有属性
    oil = "2.0T"
    # 私有属性
    __price = "5000千万"
    # 公有方法
    def oil_info():
        print("百公里油耗500升",MyCar.color)
    # 私有方法
    def __price_info():
        print("我的价格信息是保密的")
        
# 实例化对象
"""
# 对象不能调用类中无参的方法
obj = MyCar()
obj.oil_info()
"""

# 一. 定义的类访问公有成员属性和方法

# 访问公有成员属性
print(MyCar.oil)

# 访问公有成员方法
MyCar.oil_info()

# 二. 定义的类动态添加公有成员属性和方法

# 1. 添加成员属性
MyCar.color = "绿色"
print(MyCar.color)
# 查看类对象内部成员使用 __dict__ , 返回的是字典
print(MyCar.__dict__)

# 2. 添加成员方法
# 无参方法
def fangxiangpan():
    print("改造方向盘的方法")
MyCar.fangxiangpan = fangxiangpan
MyCar.fangxiangpan()
print(MyCar.__dict__)

# 有参方法
def motor(engin):
    print("动力引擎改成{}".format(engin))
MyCar.motor = motor
MyCar.motor("三缸发动机")

# lambda 表达式
MyCar.luntai = lambda name : print("使用{}的轮胎".format(name))
MyCar.luntai("米其林")

obj = MyCar()
# obj.logo = "柯尼塞格"
# print(MyCar.logo) error 类不能返回来调用对象中的成员
MyCar.logo = "别摸我,我是BMW"
obj.logo = "柯尼塞格"
print(obj.__dict__)
print(obj.logo)
7. 访问类中的私有成员
# 一. 如何访问类中的私有成员
class Plane():
	# 公有属性
	captain = "宋云杰"
	# 私有属性
	__sistem = 10
	
	# 公有绑定方法
	def fly1(self):
		print("我的飞机可以倒着飞1")
		
	# 公有普通方法
	def fly2():
		print("我的飞机可以倒着飞2")
		
	# 私有绑定方法
	def __fly_info1(self):
		print("我的飞机,百公里油耗是5万升1")
		
	# 私有普通方法
	def __fly_info2():
		print("我的飞机,百公里油耗是5万升2")
		
	def pub_info1(self):
		print(self.__sistem)
		self.__fly_info1()
		
	def pub_info2():
		print(Plane.__sistem)
		Plane.__fly_info2()

# 方法一. 调用私有成员 (不推荐使用改名策略找到私有成员,破坏封装性)
# 对象调用类中的私有成员
obj = Plane()
print(obj._Plane__sistem)
obj._Plane__fly_info1()

# 类调用类中的私有成员
print(Plane._Plane__sistem)
Plane._Plane__fly_info2()
print(Plane.__dict__)

# 方法二. 类或对象利用公有方法,间接找到私有成员(推荐)
obj.pub_info1()
Plane.pub_info2()

# 二. 实例化的对象/定义的类 删除公有成员属性和方法
print(obj.__dict__)

# 1. 公有成员属性
# 对当前对象添加成员属性 captain
obj.captain = "王浩"
# 删除当前对象中的成员属性 captain
del obj.captain
# 删除类当中的成员属性 captain
del Plane.captain
# 删除 captain 后,类和对象都没有了该属性,所有报错
# print(obj.captain) error

# 2. 公有成员方法
def add_sistem(self):
    print("因为业务需要,需要增加空姐")

Plane.add_sistem = lambda self: print("因为业务需要,需要增加空姐")

Plane.add_sistem(1)
obj.add_sistem()
# 删除类中的成员方法
del Plane.add_sistem
# obj.add_sistem() error 报错,发现被删除找不到

obj.paoniu = lambda : print("我的飞机可以用来泡妞")
obj.paoniu()
# 删除对象中的成员方法
del obj.paoniu
print(obj.__dict__)
print(Plane.__dict__)

2. 隐藏属性的意义

1. 数据属性隐藏的意义

在类内开放接口 , 让外界使用者通过接口来操作属性值 , 可以在接口之上附加任意的逻辑 , 来严格控制外界使用者对属性的操作

class Student:
    __school = "oldboy" # _Student__school = "oldboy"
    
    def __init__(obj,x,y,z):
        obj.__name = x
        obj.__age = y
        obj.gender = z
        
    def __choose(self):
        print("%s 正在选课" % self.name)
        
    def get_name(self):
        print(self.name)  # print(self._Student__name)
        
    def set_age(self,x):
        if type(x) is not int:
            print("年龄必须是整型")
            return
        self.__age = x
        
    def get_age(self):
        print(self.__age)
        
    def del_age(self):
        del self.__age
        
stu_obj1 = Student("冯疯子",18,"female")
stu_obj1.get_name()

stu_obj1.set_age("sdhfsldaf")
stu_obj1.set_age(19)
stu_obj1.get_age()
print(stu_obj1.__dict__)
2. 功能属性隐藏的意义

隔离复杂度

class ATM:
    def __card(self):
        print("插卡")
    def __auth(self):
        print("用户认证")
    def __input(self):
        print("输入取款金额")
    def __print_bill(self):
        print("打印账单")
    def __take_money(self):
        print("取款")
        
    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()
        
a = ATM()
a.withdraw()

3. property 特性

特性 property 的定义: 是一种特殊的属性 , 访问它时会执行一段功能 (函数) 然后返回值

# 例1
class People:
    def __init__(self,name,height,weight):
        self.name = name
        self.height = height
        self.weight = weight

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)
    
p = People("egon",1.81,70)
p.height = 1.84
print(p.bmi())

# 例2
class Student:
    __school = "oldboy" # _Student__school = "oldboy"
    
    def __init__(obj,x,y,z):
        obj.__name = x
        obj.__age = y
        obj.gender = z
        
    def get_name(self):
        print("访问控制")
        return self.__name
    
    def set_name(self,x):
        print("赋值控制")
        self.__name = x
        
    def del_name(self):
        print("删除控制")
        del self.__name
        
    def get_age(self):
        return self.__age
    
    def set_age(self,x):
        if type(x) is not int:
            print("年龄必须是整型")
            return
        self.__age = x
        
    def del_age(self):
        print("不能删")
        
    age = property(get_age, set_age, del_age)
    name = property(get_name, set_name, del_name)
    
stu_obj1 = Student("冯疯子",18,"female")

print(stu_obj1.age)
stu_obj1.age = "19"
del stu_obj1.age
print(stu_obj1.age)

print(stu_obj1.name)
stu_obj1.name = "EGON"
del stu_obj1.name

# 例3
class Student:
    __school = "oldboy" # _Student__school = "oldboy"
    
    def __init__(obj,x,y,z):
        obj.__name = x
        obj.__age = y
        obj.gender = z
        
    @property
    def name(self):
        print("访问控制")
        return self.__name
    
    @name.setter
    def name(self):
        print("赋值控制")
        self.__name = x
        
    @name.deleter
    def name(self):
        print("删除控制")
        del self.__name
        
stu_obj1 = Student("冯疯子",18,"female")

stu_obj1.name

4. 类中定义的函数

1. 绑定方法

谁来调用就会将谁当作第一个参数传入

1. 绑定给对象的方法

​ 类中定义的函数默认就是绑定给对象的方法 , 应该是由对象调用 , 会把对象当作第一个参数传入

2. 绑定给类的方法

​ 在类中的函数上加一个装饰器 @classmethod , 该函数就绑定给类 , 应该由类来调用 , 会把类当作第一个参数传入

2. 非绑定方法

既不与类绑定也不与对象绑定 , 就是一个普通的函数 , 谁都可以来调用 , 没有自动传参的效果

​ 在函数上添加装饰器 @ staticmethod

class People:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
    def tell_info(self):
        print("<%s:%s>" % (self.name, self.age))
        
    @classmethod
    def f1(cls):
        print(cls)
        
    @staticmethod
    def f2(x,y,z):
        print(x,y,z)
        
p1 = People("egon",18)
p1.tell_info()

print(p1.tell_info)
print(People.f1)

People.f1()

print(p1.f2)
print(People.f1)
p1.f2(1,2,3)
People.f2(1,2,3)

# 案例
import uuid
import settings

class MySQL:
    def __init__(self,ip,port):
        self.mid = self.__create_id()
        self.ip = ip
        self.port = port
        
    def tell_info(self):
        print("%s:<%s:%s>" % (self.mid,self.ip,self.port))
        
    @staticmethod
    def __create_id():
        return uuid.uuid4()
    
    @classmethod
    def from_conf(cls):
        return cls(settings.IP,setting.PORT)
    
obj = MySQL("10.10.11.11",3306)
obj.tell_info()

obj1 = MySQL.from_conf()
obj1.tell_info()
# settings.py
IP = "127.111.0.1"
PORT = 3306
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值