019-Python面向对象-方法相关、类相关补充、属性相关补充

话不多说,上代码,看结果。

print('2.3、方法相关##############################')
print('2.3.1、 方法的概念###################')
# 方法的概念
# 描述一个目标的行为动作  比如描述一个人怎样吃,怎样喝,怎样玩...
# 和函数非常类似
# 都封装了一系列行为动作
# 都可以被调用的之后,执行一系列行为动作
# 最主要的区别就是:调用方式

print('2.3.1、 方法的划分###################')
# 实例方法  默认第一个参数需要接收到一个实例
# 类方法  默认第一个参数需要接收到一个类
# 静态方法  静静的看着前面俩装逼,第一个参数啥也不默认接收
# 注意
# 1. 划分的依据是:方法的第一个参数必须要接收的数据类型
# 2. 不管是哪一种类型的方法,都是存储在类当中;没有在实例当中的
# 3. 不同类型方法的调用方式不同
# 但,不管怎么调,把握一个原则
# 不管是自己传递,还是解释器帮我们处理;最终要保证不同类型的方法第一个参数接收到的数据,是他们想要的类型


class A:
    def shilifangfa(self):
        print('实例方法')

    @classmethod
    def leifangfa(cls):
        print('类方法')

    @staticmethod
    def jingtaifangfa():
        print('静态方法')


a = A()
print(a)
# A.shilifangfa()   # TypeError: shilifangfa() missing 1 required positional argument: 'self'
A.jingtaifangfa()
A.leifangfa()

print('2.4、类相关补充##############################')
print('2.4.1、元类#############################')
print('2.4.1.1、创建类对象的类#############################')
# 对象怎样产生的?  由类创建出来的   类是不是对象  是  所以,类对象是不是由另外一个类创建出来的?  是
print('2.4.1.2、类对象的创建方式以及创建流程#############################')
# 创建方式  通过class 定义  当我们这么写这个类描述的时候, 解释器会自动的帮我们创建对应的类对象


class B:
    def C(self):
        pass


d = B()
# 通过type函数进行创建


def D(self):
    print(self)


x = type('E', (), {'123': 456, "789": 12})
print(x)
print(x.__dict__)

# 1. 检测类中是否有明确 __metaclass__属性  有, 则通过指定元类来创建这个类对象
# 2. 检测父类中是否存在__metaclass__属性   有, 则通过指定元类来创建这个类对象
# 3. 检测模块中是否存在__metaclass__属性   有, 则通过指定元类来创建这个类对象
# 4. 通过内置的type这个元类,来创建这个类对象
print('2.4.1.3、元类的应用场景#############################')
# 1)拦截类的创建
# 2)修改类
# 3)返回修改之后的类

print('2.4.2、 类的描述#############################')
# 目的  方便理清逻辑思路  方便多人合作开发时的沟通  方便生成项目文档...
# 描述方式
# 直接在类的下方,使用三个 "双引号"对就可以   需要注明类的作用, 以及类属性描述
# 至于方法, 则直接在方法下,使用三个"双引号"对描述即可  作用  参数  返回值


class Cal:
    """计算器"""

    def jiafa(self, g, h):
        """
            计算加法
        :param g: 加数1,数值类型,无返回值
        :param h: 加数2,数值类型,无返回值
        :return:  数值类型, 返回加法的结果
        """
        return g + h


j = Cal()
print(j.jiafa(1, 2))

# 生成项目文档(补充)
# 方式1
# 使用内置模块 pydoc
# 具体步骤
# 查看文档描述  python3 -m pydoc 模块名称
# 启动本地服务, 浏览文档 python3 -m pydoc -p 1234
# 生成指定模块html文档  python3 -m pydoc -w 模块名称
# 方式2
# 使用三方模块 Sphinx  epydoc doxygen
# 具体步骤  和模块之后,会进行补充

print('2.5、属性相关补充##############################')
print('2.5.1、私有化属性##############################')
# 概念  是指将一些原本公开的属性设置权限, 只能小范围访问, 其他地方访问不了
# 意义  保证数据的安全性  提高代码的可维护性
# 注意   Python并没有真正的私有化支持,但是, 可以使用下划线完成伪私有的效果  类属性(方法)和实例属性(方法)遵循相同的规则
# x  公有属性 类内部访问  子类内部访问
# 模块内其他位置访问
# 类访问  父类  派生类
# 实例访问  父类实例  派生类实例
# 跨模块访问  import形式导入   from 模块 import * 形式导入


class G:
    x = 0.123

    def test(self):
        print(G.x, self.x)


class H(G):

    def test2(self):
        print(G.x, self.x)


gg = G()
gg.test()   # 类的内部访问
hh = H()
hh.test2()  # 子类的内部访问
print(G.x, H.x, gg.x, hh.x)  # 模块内其他位置访问,通过类、子类、类实例化对象、子类实例化对象访问
wo = '569'


# _y 受保护属性
# 类内部访问   子类内部访问

# 模块内其他位置访问
# 类访问  父类  派生类  警告
# 实例访问  父类实例   派生类实例    警告

# 跨模块访问
# import形式导入   警告
# from module import * 形式导入
# 有__all__指明对应变量
# 没有__all__指明对应变量   报错


class J:
    _x = 'wo shi shui'

    def test(self):
        print(J._x, self._x)


class K(J):

    def test2(self):
        print(K._x, self._x)


jj = J()
jj.test()   # 类的内部访问
kk = K()
kk.test2()  # 子类的内部访问
print(J._x, K._x, jj._x, kk._x)  # 模块内其他位置访问,通过类、子类、类实例化对象、子类实例化对象访问

__all__ = ['_a', 'wo', '__a']
_a = "qwe"


# __z
# 私有属性
# 类内部访问
# 子类内部访问    报错

# 模块内其他位置访问
# 类访问  父类 报错    派生类  报错
# 实例访问   父类实例  报错   派生类实例  报错
# 跨模块访问
# 参照单下划线开头变量的访问原则
class Q:
    __x = '23333'

    def test(self):
        print(Q.__x, self.__x)


class W(Q):

    def test2(self):
        print(W.__x, self.__x)


qq = Q()
qq.test()   # 类的内部访问
ww = W()
# ww.test2()  # 子类的内部访问 报错  AttributeError: type object 'W' has no attribute '_W__x'
# print(Q.__x, W.__x, qq.__x, ww.__x)  # 模块内其他位置访问,通过类、子类、类实例化对象、子类实例化对象访问
__a = "zxc"

# 私有属性的实现机制
# 名字重整(Name Mangling)   重改__x为另外一个名称, 如  _类名__x
# 目的  防止外界直接访问   防止被子类同名称属性覆盖
# 应用场景  数据保护  数据过滤
print(Q.__dict__)   # '__module__': '__main__', '_Q__x': '23333', 。。。。。。
# print(Q.__x)    # AttributeError: type object 'Q' has no attribute '__x'
print(Q._Q__x)


class Country:
    def __init__(self):
        self.__country = '齐国'

    def setCountry(self, country):
        self.__country = country

    def getCountry(self):
        return self.__country


c1 = Country()
c2 = Country()
c3 = Country()
# print(c1.__country)     # AttributeError: 'Country' object has no attribute '__country'
# print(c1._Country__country)  # 不建议这么用,要这样还设置私有化属性干啥
# c2.__country = '秦国'
# print(c2.__country)  # 新建的实例属性,不是修改类属性!!!
# print(c2.__dict__)  # {'_Country__country': '齐国', '__country': '秦国'}
c3.setCountry('燕国')
print(c3.getCountry())
print(c1.__dict__)  # {'_Country__country': '齐国'}
print(c3.__dict__)  # {'_Country__country': '燕国'}
# 补充
# xx_   "变量名_" 这个格式是为了与系统属性作区分
# __xx__  一般为系统内置属性或方法, 所以以后命名注意避免

print('2.5.2、只读属性##############################')
# 概念  一个属性(一般指实例属性), 只能读取, 不能写入
# 应用场景  有些属性, 只限在内部根据不同场景进行修改, 而对外界来说, 不能修改, 只能读取
# 比如   电脑类的网速属性, 网络状态属性

# 方式1
# 方案
# 全部隐藏  私有化  既不能读  也不能写
# 部分公开   公开读的操作
# 具体实现   私有化   通过"属性前置双下划线"实现

# 部分公开   通过公开的方法
# 优化   property
# 作用
# 将一些"属性的操作方法"关联到某一个属性中


class Xiong:
    def __init__(self):
        self.animal1 = '熊大'
        self.animal2 = '熊二'

    def getanimal(self):
        return self.__animal1


a1 = Xiong()
print(a1.getanimal)


class Xiong:
    def __init__(self):
        self.__animal1 = '熊大'
        self.__animal2 = '熊二'

    @property
    def animal(self):
        return self.__animal1

a1 = Xiong()
# a1.animal = '蹦蹦'  # AttributeError: can't set attribute  只读属性,修改不了!!
print(a1.animal)
print(a1.__dict__)


# 概念补充
# 经典类   没有继承(object)
# 新式类   继承(object)
# Python2.x版本定义一个类时, 默认不继承(object)
# Python3.x版本定义一个类时, 默认继承(object)
# 建议使用   新式类
# property  在经典类中   只能管理一个属性的读取操作
# 在新式类中   可以管理一个属性的删改查操作
# class C(object):
#             def getx(self): return self._x
#             def setx(self, value): self._x = value
#             def delx(self): del self._x
#             x = property(getx, setx, delx, "I'm the 'x' property.")
class Xiong:
    def __init__(self):
        self._animal = '熊大'
        self._animal2 = '熊二'

    def getanimal(self):
        return self._animal

    def setanimal(self, value):
        self._animal = value

    def delanimal(self):
        del self._animal2

    animal = property(getanimal, setanimal, delanimal)


a1 = Xiong()
print(a1.animal)
a1.animal = "@@@虫大"
print(a1.animal)

# class C(object):
#             @property
#             def x(self):
#                 "I am the 'x' property."
#                 return self._x
#             @x.setter
#             def x(self, value):
#                 self._x = value
#             @x.deleter
#             def x(self):
#                 del self._x


class Forest:

    def __init__(self):
        self._animal = '熊大'
        self._animal2 = '熊二'

    @property
    def animal(self):
        return self._animal

    @animal.setter
    def animal(self, value):
        self._animal = value

    @animal.deleter
    def animal(self):
        del self._animal2


b1 = Forest()
print(b1.animal)
b1.animal = "虫大"
print(b1.animal)

# 方式2
# 方案  借助系统内置的方法进行拦截
# 具体实现   __setattr__方法
# 当我们使用 "实例.属性 = 值" 这种格式给一个实例增加或修改属性的时候, 都会调用系统内置的这个方法
# 在这个方法的内部, 才会真正的把属性以及对应的值给存储到 __dict__当中
# 解决方案  在这个方法中, 进行拦截


class senlin:

    def __setattr__(self, key, value):
        print('^^^', key, value)
        if key == "animal" and key in self.__dict__.keys():
            print("这个属性是只读属性, 不能设置数据")

        else:
            self.__dict__[key] = value


g1 = senlin()
print(g1.__dict__)
g1.animal2 = "虫二"
print(g1.__dict__)
g1.animal = "熊大"
print(g1.__dict__)

print('2.5.3、内置特殊属性##############################')
# 类属性
# __dict__ : 类的属性    __bases__ : 类的所有父类构成元组
# __doc__ :类的文档字符串  __name__: 类名   __module__: 类定义所在的模块
# 实例属性
# __dict__ : 实例的属性
# __class__: 实例对应的类

结果如下图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就先这样,遇到别的再补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值