Python中type、object和class的关系,一图即懂

没有文字描述,因为图足够好!

在这里插入图片描述

  • 查看一个类的基类可以使用__bases__方法
  • 查看一个实例对应的类是谁,可以用__class__方法
class Animal:
    pass
class User:
    pass
class Dog(Animal, User):
    pass

if __name__ == "__main__":
    print(Dog.__bases__)  # (<class '__main__.Animal'>, <class '__main__.User'>)
    print(User.__bases__)  # (<class 'object'>,)
print(int.__bases__)  # (<class 'object'>,)
print(float.__bases__)  # (<class 'object'>,)
print(bool.__bases__)  # (<class 'int'>,)
print(object.__bases__)  # ()
class User:
    pass
u = User()
print(u.__class__)  # <class '__main__.User'>
# Python万物皆对象,类本质也是个对象,所以肯定也是由另外的类创建出来的
print(User.__class__)  # <class 'type'>
print(type.__class__)  # <class 'type'>
print(type.__bases__)  # <class 'type'>

这里补充一下type的常见用法吧:

  • type()可以用来创建类
  • 还可以自定义元类
# 这个函数用来动态的创建类对象
# 这就是动态语言的特性,在Python中实现是非常简单的,而在Java中是很难的
# 但是这样去写代码还是复杂的,因为还是需要我们去定义class语句
def create_class(name):
    if name == "user":
        class User:
            def __str__(self):
                return "user"
        return User
    if name == "company":
        class Company:
            def __str__(self):
                return "company"
        return Company
if __name__ == "__main__":
    MyClass = create_class("user")
    my_obj = MyClass()
    print(my_obj)  # user
# 使用type动态的灵活的创建类,不用去写class语法
if __name__ == "__main__":
    # 类的名字是User,()代表不继承任何基类,{}代表类属性为空
    User = type("User", (), {})
    my_obj1 = User()
    print(my_obj1)  # <__main__.User object at 0x108861700>
    Company = type("Company", (), {"name":"cop"})
    my_obj2 = Company()
    print(my_obj2.name)  # cop
    print(Company.__dict__)  # {'name': 'cop', ...}
# 使用type动态的灵活的创建类,且定义一些方法
def say(self):
    return self.name

def see(cls):
    return cls.name

if __name__ == "__main__":
    User = type("User", (), {"name": "class_name", "say": say, "see": classmethod(see)})
    my_obj = User()
    print(my_obj.say())  # class_name
    print(
        User.__dict__,
    )  # {'name': 'class_name', 'say': <function say at 0x10aa7b0d0>, 'see': <classmethod object at 0x10abfafd0>, ...}
    print(User.see())  # class_name
# 使用type动态的灵活的创建类,且继承一些基类
class BaseClass:
    def answer(self):
        return "I am BaseClass"
if __name__ == "__main__":
    # 注意元组中只有一个元素是一定要加逗号的
    User = type("User", (BaseClass,), {})
    my_obj = User()
    print(my_obj.answer())  # I am BaseClass
# 这是个自定义元类的demo
# 用于创建一个类时,自动将类中的方法名改为大写
# 例如:User中的方法名say,将被改为SAY
# 用法:在类中添加metaclass=UpperAttrMetaclass即可
# 例如:class User(metaclass=UpperAttrMetaclass):
# 如果我们需要自定义元类就需要继承自type


class UpperAttrMetaclass(type):
    """自定义元类的目的就是为了控制User类实例化的过程"""

    def __new__(cls, *args, **kwargs):
        """
        args: 是个tuple类型,和type(name, bases, dict)的写法是一样的,你可以在type类的源码中看到这样的写法
        """
        print("*" * 50)
        name = args[0]  # User
        bases = args[1]  # (<class '__main__.A'>,)
        dct = args[2]  # {'__module__': '__main__', '__qualname__': 'User', '__doc__': '...', '__init__': <function User.__init__ at 0x106f120d0>, 'say': <function User.say at 0x106f12160>}
        kwds = kwargs  # {},这里始终为空
        print(name, bases, dct, kwds, sep="\n", end="\n" + "*" * 50 + "\n")
        uppercase_attr = {}
        for name, value in dct.items():
            if not name.startswith("__"):
                uppercase_attr[name.upper()] = value
            else:
                uppercase_attr[name] = value
        return super().__new__(cls, name, bases, uppercase_attr, **kwds)


class A:
    """没有任何意义,只是为了让上面自定义元类的bases参数打印不为空,便于理解而已"""
    pass


class User(A, metaclass=UpperAttrMetaclass):
    """这样就指明当我们创建User类的时候使用的元类是UpperAttrMetaclass"""

    def __init__(self, name):
        self.name = name

    def say(self):
        print(f"i am {self.name}")


print(hasattr(User, "say"))  # False
print(hasattr(User, "SAY"))  # True
f = User("foo")
print(f)  # <__main__.User object at 0x106f16760>
f.SAY()  # i am foo
# f.say()  # AttributeError: 'User' object has no attribute 'say'
print(f.__dict__)  # {'name': 'foo'}
print(
    User.__dict__,
)  # {'__init__': <function User.__init__ at 0x106f120d0>, 'SAY': <function User.say at 0x106f12160>, ...}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/231097.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux初级学习

(420条消息) 红帽认证-RHCSA_rhcsa红帽认证_yyyzf的博客-CSDN博客 OS&#xff1a;用户和机器的接口&#xff0c;UI:CMD,GUI shell: 通用格式 命令 选项&#xff08;调控功能&#xff09; 参数&#xff08;操作对象&#xff09;参数 省略参数对象一般使用当前目录作为参数对…

Linux下C++静态链接库的生成以及使用

目录 一.前言二.生成静态链接库三.使用静态链接库 一.前言 这篇文章简单讨论一下Linux下如何使用gcc/g生成和使用C静态链接库&#xff08;.a文件&#xff09;。 二.生成静态链接库 先看下目录结构 然后看下代码 //demo.h#ifndef DEMO_H #define DEMO_H#include<string&g…

C#-快速剖析文件和流,并使用

目录 一、概述 二、文件系统 1、检查驱动器信息 2、Path 3、文件和文件夹 三、流 1、FileStream 2、StreamWriter与StreamReader 3、BinaryWriter与BinaryReader 一、概述 文件&#xff0c;具有永久存储及特定顺序的字节组成的一个有序、具有名称的集合&#xff1b; …

题目:挑选子串(蓝桥OJ 1621)

题目描述&#xff1a; 解题思路&#xff1a; 采用双指针的快慢指针。与蓝桥OJ1372类似。 图解 题解&#xff1a; #include <bits/stdc.h> using namespace std;const int N 1e5 9; int a[N];int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int n, m…

网站内容审核功能的重要性

网站内容审核功能的重要性在保护用户权益、维护网站形象、遵守法律法规等方面都起到了至关重要的作用。 维护网站的合法性和道德性&#xff1a;网站内容审核功能的存在可以帮助过滤和删除违法、淫秽、恶意、诈骗等不良内容&#xff0c;保证网站内容的合法性和道德性。 保护用…

实现跨VLAN通信、以及RIP路由协议的配置

一、如下图片&#xff1a; 1. 按照拓扑图所示&#xff0c;将8台计算机分别配置到相应的VLAN中。&#xff08;20分&#xff09; 2. 配置实现同一VLAN中的计算机可以通信。&#xff08;22分&#xff09; 3. 配置实现PC1,PC2,PC3,PC4可以互相通信&#xff0c;PC5,PC6,PC7,PC8可以互…

面向对象中的单例模式

1、什么是设计模式 设计模式就是前人根据实际的问题提出的问题解决方案&#xff0c;我们把这种就称之为设计模式。 2、单例模式 单例模式是一种常见的设计模式&#xff01; 所谓的设计模式&#xff0c;不是一种新的语法&#xff0c;而是人们在实际的应用中&#xff0c;面对…

计算机考研408-计算机网络、操作系统整书知识点脑图

计算机网络、操作系统整书知识点脑图 今天突然想起来考研期间为了方便记忆&#xff0c;费了很大力气整理了计算机网络、操作系统两本书知识点的脑图&#xff0c;想着放着也没啥用&#xff0c;分享出来给大家看看 但是思维导图格式的东西好像没法直接发成文章&#xff0c;要是…

(三潮来袭)探寻2023年科技变革潮流与2024年前瞻展望

2023年对于IT行业来说是一个动荡而又充满变革的一年。随着世界逐渐走出前几年的挑战&#xff0c;企业逐渐复苏&#xff0c;但这个行业仍然在经历着激烈的变革。在这个时候&#xff0c;我们看到了一些引人注目的技术变化和未来的趋势。 一、2023年回顾 关键词&#xff1a;Chat…

手持式安卓主板_PDA安卓板_智能手持终端方案

手持式安卓主板方案是一种智能终端设备&#xff0c;具备自动对焦和闪光灯功能&#xff0c;可以在昏暗的环境下快速扫描二维码并轻松采集数据。该方案还提供多渠道支付和数据采集功能&#xff0c;为用户提供了便捷的体验。 该方案的产品基于手持式安卓主板&#xff0c;并搭载了八…

Unity中后处理简介

文章目录 前言一、后处理的原理二、我们看一下Unity文档中&#xff0c;内置的后处理前后的效果后处理前&#xff1a;后处理后&#xff1a; 前言 我们在这篇文章中&#xff0c;了解一下Unity中的后处理效果 后期处理概述 一、后处理的原理 在后处理的过程中&#xff0c;我们主…

爱智EdgerOS之深入解析安全可靠的开放协议SDDC

一、协议简介 在 EdgerOS 的智慧生态场景中&#xff0c;许多智能设备或传感器的生命周期都与 SDDC 协议息息相关&#xff0c;这些设备可能是使用 libsddc 智能配网技术开发的&#xff0c;也有可能是因为主要功能上是使用其他技术如 MQTT、LoRa 等但是设备的上下线依然是使用上…

金蝶云星空表单服务规则设置-基础资料和复选框判断

文章目录 金蝶云星空表单服务规则设置-基础资料和复选框判断语法规则业务需求开发实现测试 金蝶云星空表单服务规则设置-基础资料和复选框判断 语法规则 基础资料判断&#xff1a;标识null 复选框判断打钩&#xff1a;标识true 业务需求 售后单审核时&#xff0c;如果物料启…

【接口技术】实验5:模/数(ADC0809)和数/模(DAC0832)转换

实验5 模/数(ADC0809)和数/模(DAC0832)转换实验 一、实验目的 1&#xff1a;了解模/数转换的基本原理&#xff0c;掌握ADC0809的使用方法。 2&#xff1a;了解数/模转换的基本原理&#xff0c;掌握DAC0832的使用方法。 二、实验内容 &#xff08;1&#xff09;模/数转换器…

浅析以太网接口及串口转以太网技术

浅析以太网接口 以太网相关接口主要包括&#xff1a;MII/RMII/SMII以及GMII/RGMII/SGMII接口。 一、MII接口 MII&#xff08;Media Independent Interface&#xff09;介质无关接口或称为媒体独立接口&#xff0c;它是IEEE-802.3定义的以太网行业标准。它包括一个数据接口和…

Qt + MySQL(简单的增删改查)

Qt编译MySql插件教程 帮助&#xff1a; SQL Programming QSqlDatabase 静态函数 1.drivers()&#xff0c;得到可以使用的数据库驱动名字的集合 [static] QStringList QSqlDatabase::drivers();2.addDatabase()&#xff0c;添加一个数据库实例 [static] QSqlDatabase QSql…

kennard-stone算法实现样本集划分(ks算法)

目录 一、 Kennard-Stone算法原理&#xff08;KS算法&#xff09; 二、Kennard-Stone算法作用 三、代码 四、对选出来的train样本使用T-SNE算法进行绘制 五、参考链接 一、 Kennard-Stone算法原理&#xff08;KS算法&#xff09; KS算法原理&#xff1a;把所有的样本都看…

【C语言】操作符详解(一):进制转换,原码,反码,补码

目录 操作符分类 2进制和进制转换 2进制转10进制 10进制转2进制 2进制转8进制和16进制 2进制转8进制 2进制转16进制 原码、反码、补码 操作符分类 操作符中有一些操作符和二进制有关系&#xff0c;我们先铺垫一下二进制的和进制转换的知识。 2进制和进制转换 其实我们经…

在OpenCV基于深度学习的超分辨率模型实践

1. 引言 OpenCV是一个开源的计算机视觉库&#xff0c;拥有大量优秀的算法。基于最新的合并&#xff0c;OpenCV包含一个易于使用的接口&#xff0c;主要用于实现基于深度学习方法的超分辨率&#xff08;SR&#xff09;。该接口包含预先训练的模型&#xff0c;这些模型可以非常容…

K8s构建的mysql无法远程连接

最近在写一个老师布置的大作业&#xff0c;都是老师写好的yaml文件&#xff0c;都是没问题的&#xff0c;但是构建的mysql无法远程连接。 尝试了网上的很多方法&#xff0c;都失败了&#xff0c;我的构建过程应该是没什么错误的&#xff0c;所以网上的方法并不奏效&#xff0c…
最新文章