Python面向对象之方法篇 + 元类

Python面向对象之方法篇 + 元类,第1张

Python面向对象方法篇 + 元类 Python面向对象中的方法

参考链接:【Python】零基础入门——面向对象编程(强烈推荐)_哔哩哔哩_bilibili

python面向对象的方法种类

python面向对象中的方法的种类有:

划分的依据是:方法的第一个参数必须要接受的数据类型。

同时不管是哪一种类型的方法,都是存储在类当中;没有在实例对象当中。

不同类型方法的调度方式会不同。

  • 实例方法:默认第一个参数需要接收到一个实例
  • 类方法:默认第一个参数需要接收到一个类
  • 静态方法:第一个参数任意,没有默认接收
class Student:
    # 实例方法
    def study(self):
        print("I am learning",self)
        pass
    # 类方法
    @classmethod
    def classmate(cls):
        print("这是一个同班同学类",cls)
        pass
    # 静态方法
    @staticmethod
    def grow_up():
        print("这是一个静态方法")
        pass

方法的不同作用

在三种方法之间的不同用途和区别:

  • 实例方法中,首先最需要注意的就是,self其实就是这个实例对象本身,也就是说是这个对象的地址(ID号),这个在调用方法或者输出对象,在最后的地址可以验证。同时self这个形参并不是一定要叫self,可以随便取名字,但规范上要求写成self。虽然是自动传,所以self这个参数必须写,实例方法一般在使用实例的时候能够很好的调用,不需要传参数,直接对象点击就传过去

  • 在类方法中,首先最需要注意的就是,cls表示的是这个类本身,也就是说这个用类来调用的方法,同时类方法也是只需要用到类的时候进行调用

  • 静态方法则就是不需要用到类和对象实例的时候进行使用,较为方便

方法的存储

在老师的研究下表明,这些方法无论是实例方法、类方法还是静态方法, 一开始在对象里面都是不存在的,都保存在了类里面,这个从类的dict属性中可以看到,代码如下:

class Student:
    # 实例方法
    def study(self):
        print("I am learning",self)
        pass
    # 类方法
    @classmethod
    def classmate(cls):
        print("这是一个同班同学类",cls)
        pass
    # 静态方法
    @staticmethod
    def grow_up():
        print("这是一个静态方法")
        pass
    pass
ZhangSan = Student()
# 这里会输出为空
print(ZhangSan.__dict__)
# 这里会输出为键值对。,可以发现方法存储在类里面
print(Student.__dict__)

方法的调用方式

  • 实例方法的标准调用方式与其他调用方式,方法见下面例子

    class Student:
        # 实例方法
        def study(self,subject):
            print("I am learning",subject)
            pass
        # 类方法 驱动注解(视频中称之为装饰器)
        @classmethod
        def classmate(cls):
            print("这是一个同班同学类",cls)
            pass
        # 静态方法
        @staticmethod
        def grow_up():
            print("这是一个静态方法")
            pass
        pass
    ZhangSan = Student()
    # 实例方法标准调用方式,不需要写第一个形参
    ZhangSan.study("math")
    # 实例方法其他调用:直接找到函数本身进行调用,例如
    Student.study(ZhangSan,"math")
    # 或者如下:
    func = Student.study
    func(ZhangSan,"math")
    # 类方法调用方式:首先如果你直接使用类名进行调用,那OK没有问题,如果你使用类的是实例对象进行调用,
    # 那么python会自动找到其中对象所对应的类,传过来进行调用,类方法与C++ Java中的静态方法是不一样的
    # 注解的作用是:在保证原有函数的功能不改变情况下,增加函数的功能(偏底层的功能)
    Student.classmate()
    ZhangSan.classmate() # 会直接把对象的类传过去
    # 甚至如下方式也可以
    func = Student.classmate()
    func(Student)
    # 甚至可以这样去使用,但这样的话,就有点违背开发者的意志了
    class S:
        pass
    S.study()  # 这里输出的类名是S
    # 静态方法的调用方式:其不需要接收第一个默认参数,既可以通过类进行调用,也可以通过实例来进行调用
    Student.classmate()
    

ZhangSan.classmate()

或者如下这种方式:

func = Student.classmate()
func(Student)


**不同的方法访问不同的属性的规律**

这里其实讲过了,因为实例对象是可以访问类对象的属性,但类不可以,原因是对象保存了类对象的地址,但类是访问不到对象的属性的,因为类没有保存每一个实例对象的地址,所以对于实例方法而言,实例方法会访问到

```python
class Student:
  age = 0
  # 实例方法
  def study(self):
      print(self.age)
      print(self.num)
      pass
  # 类方法 驱动注解(视频中称之为装饰器)
  @classmethod
  def classmate(cls):
      print(self.age)
      print(self.num)
      pass
  # 静态方法
  @staticmethod
  def grow_up():
      print(self.age)
      print(self.num)
      pass
  pass
ZhangSan = Student()
ZhangSan.num = 10
# 下面可以成功运行
ZhangSan.study()
# 下面运行报错,表示没有num属性
ZhangSan.classsmate()
# 所以因此静态方法也是访问不到的

元类

创建类对象的类,就是个元类。值得一说的是python里面数据类型全部都是对象

num = 10
print(num__class__)
print(num.__class__.__class__)
# 输出元类type  type是最大的那个元类

类对象的创建方式

# 上面写了什么叫做元类,那我们这里就要开始创建类对象
num = 10
# 打印出num对象的类名称
print(type(num))
# 除此之外type还可以创建类对象,例如下面我可以创建一个Student的对象,其中第二个参数(元组)表示的是Student的父类是什么,第三个参数表示的dict属性,可以添加属性和方法,返回回去的变量ZhangSan,原视频中使用的函数名当地址
ZhangSan = type("Student",(),{“age”: 18,"study": 地址})

元类的查找机制

# 在python当中可以通过__metaclass__来赋予一个元类
# 例如
class Student:
    __metaclass__ = Proson
    pass
# 或者
class Student(metaclass = Proson):
    __metaclass__ = Proson
    pass
# 而类在创建过程中,首先是从自己__metaclass__里面去找,如果自己没有,则先去父类里面去找,然后到父类里面的__metaclass__去找,如果父类里面也没有,就会直接去文件模块里面找,一般来说模块里面会标注出__metaclass__是xxx 这样通过继承可以控制所有类的对象的元类,模块也是...
# 元类的应用场景:
# 1. 拦截类的创建
# 2. 修改类
# 3. 返回修改之后的类
# 4. 后面补充

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5680026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存