【python基础】十一、Python 面向对象 魔术方法

面向对象

内容

  • 对象
  • 属性 --> 名词、形容词:状态
  • 方法 --> 动词 :动作

类名 : 首字母大写 + 驼峰式命名

ValueError TypeError StopIterator

  • 所有的类 继承 祖宗类: Object类
定义
class Phone(object):    # python2 必须
    pass
class Phone():          # python3 默认object    
    pass
class Phone:            # () 也可以省略
    pass
class XiaoMi(Phone):  # (父类)
    # 属性
    # 方法

空类 也可 动态添加属性


  • 区别 类属性 和 对象属性
# 定义类和属性
class Student(object):
    # 类属性
    name = 'Jam'
    age = 24


s1 = Student()
print(s1.name)  # 首先 判断 s1 有没有name 属性, 没有 则去 类中 取对应的 类属性(初始值)
s1.age = 2
print(s1.age)   # 首先 判断 s1 有没有age 属性,此时的 age 属性 被重新赋值过, 因此它是 s1的 对象属性

try:
    print(s1.sex)
except AttributeError as ae:
    print(ae, 'and add it!')
    s1.sex = 0  # 新增 对象属性

# 类属性 通过类名 使用
Student.name = 'Null'
s2 = Student()
print(s2.name)

  • 类中的方法

    • 普通方法
    • 魔术方法一:
      • 共性特征
      • 不同于类属性
    • 类方法
    • 静态方法
class xxx():
    def __init__(self):
        self.price = 2999   
        
# init 传值    
class xxx(object):
    def __init__(self, price):
        self.price = price
        
ooo = xxx(35)   # 传参 实例化   

面向对象实践:

# cat
class Cat(object):
    type = '猫'
    type_en = 'cat'

    def __init__(self, nickname, age, color):
        self.nickname = nickname
        self.age = age
        self.color = color

    def eat(self, food):
        print('{}喜欢吃{}'.format(self.nickname, food))

    def catch_mouse(self, weight, color):
        print('{} 抓了一只{}kg的{}老鼠!'.format(self.nickname, weight, color))

    def sleep(self, hour):
        if hour < 5:
            print('需要睡觉!')
        else:
            print('可以工作!')

    def show_info(self):
        print('正在打印 详细信息')
        print(self.nickname, self.age, self.color)


cat_1 = Cat('花花', 2, '灰色')

cat_1.catch_mouse(0.5, '黑色')
cat_1.sleep(8)
cat_1.eat('小鱼干')

类方法

认识、了解 即可

  • 特点:
  1. 定义需要依赖装饰器
  2. 自动传入的参数不是对象,是类
  3. 类方法中只可以使用类属性,不可以使用
  4. 在创建完成类,实例化对象之前,类方法已经写入类内存
  5. 类方法 不能调用 普通方法 - 同级普通方法可以互相调用
  • 作用

只能访问类属性 和 类方法,使用于 需要 创建对象 之前完成的动作,

# 类方法
# 类方法
class Dog(object):
    __age = 2

    def __init__(self, nickname):   # 魔术方法  依赖于self(这个对象)
        self.nickname = nickname

    def run(self):                  # 普通方法 依赖于self
        print('run')

    @classmethod                    # 类方法 前面加 @classmethod
    def test(cls):                  # 自动传入 cls(这个类)
        __age += 1
        print(cls.__age)
        # print(self.run())
        # print(cls.nickname)       # AttributeError:

Dog.test()
d = Dog('DaHuang')
# Dog.__age
# d.__age
d.run()
d.test(d)

私有变量

class Person():
    __age = 18

静态方法

class Person():
    __age = 18
    def __init__(self):
        self.name = 'jack'
    
    @staticmethod
    def static_func():
        # 不能访问 对象属性 不能出现 self
        # 可以访问 类属性,但不通过 cls
        print(Person.__age)
    
  • 静态方法 与 类方法相似
  1. 由 @staticmethod 定义
  2. 能 通过类名 访问类属性
  3. 不能使用 self、cls 参数
  4. 加载时机 同 类犯法
  • 静态 和 类方法 很少写到,认识了解即可

  • 面试可能会问,读源码可能会出现

  • 相同:

  1. 都只能访问类的属性和方法,对象的无法访问
  2. 都可以通过类名调用
  3. 都在对象实例化之前创建 因此不依赖于对象
  • 不同:
  1. 装饰器不同
  2. 类方法自带传入cls参数,静态方法默认无传参
  • 普通方法 与 两者的区别
  1. 普通 无装饰器
  2. 依赖于对象 self
  3. 只有实例化对象后 才能调用普通方法

魔术方法

魔术方法就是类/对象中的一个方法
区别在于普通方法需要调用
魔术方法是在特定时刻自动触发

import sys

class MagicFunc():
    param = 'Para'

    def __new__(cls, *args, **kwargs):
        print('__new__')
        """
        实例化:
        系统默认 存在__new__方法 用于 为实例化对象 申请开辟内存空间
        重写 __new__ 则不会自动为新对象开辟新地址,从而导致 __init__ 不被调用
        return 开辟的地址
        """
        r = object.__new__(cls, *args, **kwargs)
        print(r)
        return r

    def __init__(self):
        print('__init__')
        """
        初始化
        对象实例化后,为其初始化
        """
        print(self)


    def __call__(self, *args, **kwargs):
        print('__call__')   # 将对象当作函数p() 来使用时触发
        print(*args)

    def __del__(self):
        print('__del__')
        """
        1. 对象赋值
        析构
        :return:
        """
        print(self)

    def __getattr__(self, item):
        pass


mf = MagicFunc()

mf('hello','hi')
mf('hello')# 触发__call__

mf_c1 = mf # 克隆mf 将内存空间地址赋值
mf_c2 = mf # clone mf



del mf_c1       # 删除 mf_c1 ,断开与 mf 的链接
del mf_c2
print(sys.getrefcount(mf))      # 查看mf 内存空间 被使用几次,包含本次


魔术方法 参考

在b站学习中

个人主页

学习链接

欢迎 批评 指正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章