type简介

type在Python中的作用是创建一个类。

我们创建类的时候一般会使用这样的方法:

# -*- coding:utf-8 -*-

class Student(object):

    country = "China"

    def add(self,x:int,y:int)->int:
return x+y s1 = Student()
print(s1.country)
print(s1.add(12,23))

当然也可以使用type方法创建类,效果与上面的方法一样:

# -*- coding:utf-8 -*-
Student = type(
"Student",
# 元组只有单个元素后面需要加逗号!
(object,),
{
'country':"China",
'add':lambda self,x,y:x+y
}
) s1 = Student()
print(s1.country)
print(s1.add(12,33))

不过,我最近看公司某个封装好的功能的源码的时候,发现了它另外的一个用途,就是“在对象方法中调用类方法”(什么,你分不清对象方法、类方法与静态方法?请自行Google)。

在对象方法中使用类方法

基本操作

假设我们现在有一个Student类,要在对象方法中调用类方法,可以这样写:

# -*- coding:utf-8 -*-
class Student(object): @classmethod
def get_country(cls):
return "China"
def __init__(self,name):
self.name = name
# type(self),在对象方法中使用类的方法
self.country = type(self).get_country()
def get_my_country(self):
# type(self),在对象方法中使用类的方法
return type(self).get_country()
if __name__ == '__main__': s1 = Student('wanghw') print(s1.country) # China
print(s1.get_my_country()) # China # 事实上,对象也可以直接调用“类方法”,但是为了“规范”,我们不这么直接让对象直接调用“类方法”
print(s1.get_country()) # China

起一个与类方法同名的对象方法再试试

上面的基本操作也许大家都明白,现在我们试一下极端的方式:起一个与类方法同名的对象方法,看看效果如何:

# -*- coding:utf-8 -*-
class Student(object): @classmethod
def get_country(cls):
return "China" def __init__(self,name):
self.name = name
# type(self),在对象方法中使用类的方法
self.country = type(self).get_country() def get_my_country(self):
# type(self),在对象方法中使用类的方法
return type(self).get_country() # 起一个与类方法同名的对象方法
def get_country(self):
return "English"
if __name__ == '__main__': s1 = Student('wanghw') print(s1.country)
print(s1.get_my_country())

运行程序,你会发现上报了一个这样的错误:

TypeError: get_country() missing 1 required positional argument: 'self'

实际上,此时我们实例化的Student对象用的是自己的方法!而上面的__init__初始化方法与get_my_country方法的调用者是类Student,缺少了参数self,我们把程序修改如下(在get_country中加上参数self再试试):

# -*- coding:utf-8 -*-
class Student(object): @classmethod
def get_country(cls):
return "China" def __init__(self,name):
self.name = name
# type(self),在对象方法中使用类的方法
self.country = type(self).get_country(self) def get_my_country(self):
# type(self),在对象方法中使用类的方法
return type(self).get_country(self) # 起一个与类方法同名的对象方法
def get_country(self):
return "English" if __name__ == '__main__': s1 = Student('wanghw') print(s1.country) # English
print(s1.get_my_country()) # English

由此,我们可以得出结论:如果对象方法与类方法同名的话,对象会优先调用自己的方法!

其他相关的知识点详见这篇博客

其他关于type的说明,我自己之前总结过一篇关于type与isinstance的区别的文章,还有我在网上找的一篇很不错的关于type的说明的文章:

https://www.cnblogs.com/paulwhw/p/10637282.html

https://www.cnblogs.com/zy0517/articles/9046549.html

使用type在对象方法中调用类方法的更多相关文章

  1. Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)

    Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...

  2. Java中对象方法的调用过程&动态绑定(Dynamic Binding)

    Java面向对象的最重要的一个特点就是多态, 而多态当中涉及到了一个重要的机制是动态绑定(Dynamic binding). 之前只有一个大概的概念, 没有深入去了解动态绑定的机理, 直到很多公司都问 ...

  3. Java-main方法中调用非static方法

    java的calss中,在public static void main(String[] args) { }方法中调用非static的方法:在main方法中创建该calss的对象,用对象调用非sta ...

  4. springMVC在普通方法中调用service方法

    SpringContextUtil类 package com.common.util; import org.springframework.beans.BeansException;import o ...

  5. JAVA Main方法中调用非静态方法

    在JAVA中静态方法中只能调用其他,静态方法.main方法都是静态方法,如果想调用其它的方法,要么只能是其它的静态方法.还有一种方法就是将当前类实例化在调用它的非静态方法 public class t ...

  6. 动态的创建Class对象方法及调用方式性能分析

    有了Class对象,能做什么? 创建类的对象:调用Class对象的newInstance()方法 类必须有一个无参数的构造器. 类的构造器的访问权限需要足够. 思考?没有无参的构造器就不能创建对象吗? ...

  7. 为什么Java中 wait 方法需要在 synchronized 的方法中调用?

    另一个棘手的核心 Java 问题,wait 和 notify.它们是在有 synchronized 标记的方法或 synchronized 块中调用的,因为 wait 和 modify 需要监视对其上 ...

  8. JS高级 —— 普通函数、构造函数、对象方法的调用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  9. javascript中string对象方法中的slice、substring、substr的区别联系

    1.slice.substring.snustr均属于String的对象方法,用于截取或提取字符串片段,三者均布破坏原先的字符串,而是以新的字符串返回被提取的部分. <script> va ...

随机推荐

  1. 在.NET Core 3.0中发布单个Exe文件(PublishSingleFile)

    原文:在.NET Core 3.0中发布单个Exe文件(PublishSingleFile) 假设我有一个简单的" Hello World"控制台应用程序,我想发送给朋友来运行.朋 ...

  2. 面向新手的Web服务器搭建(一)——IIS的搭建

    很多童鞋说自己是做移动开发的,想挂个简单的Web API,可是服务器又不会搭,这样一来测试就成了问题.看看网上的教程,发现略难懂,而且大多是一个转一个,没价值,所以干脆写几篇文章讲讲简单的Web服务器 ...

  3. 为Xcode配置Git和Github

    Xcode.Git和Github是三个伟大的编程工具.本文记录一下如何在Xcode中使用Git作为源代码控制工具,以及如何将本地的Git仓库和远程Github上的仓库集成起来. 1. 如何为新建的Xc ...

  4. Delphi 基于组件的编程思想

  5. 设备中LPC2368芯片个例参数问题导致故障的分析

    最近公司的设备客户报告在终端客户那里出现了板卡加热不受控,出现了持续加热导致设备一些贵重部件损坏.由于历史上很多现场问题,板卡什么拆到别的地方搭复现平台,基本都是以失败告终,所以出差去现场分析. 过程 ...

  6. linux如何配置使用sendEmail发送邮件

    sendEmail是一个轻量级.命令行的SMTP邮件客户端.如果你需要使用命令行发送邮件,那么sendEmail是非常完美的选择.使用简单并且功能强大.这个被设计用在php.bash.perl和web ...

  7. 2019-2020-1 20199319《Linux内核原理与分析》第三周作业

    操作系统是如何工作的 基础知识 1.计算机的三个法宝:存储程序计算机.函数调用堆栈机制.中断. 2.堆栈的具体作用:记录函数调用框架.传输函数参数.保存返回值的地址.提供函数内部局部变量的存储空间. ...

  8. sql server查询在线用户

    select request_session_id spid, object_name(resource_associated_entity_id) tableName from sys.dm_tra ...

  9. linux系统监控sar命令

    linux系统监控sar命令详解 sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告, 包 ...

  10. java.lang.String (JDK 1.8)

    研究一个类之前我们来说说类的构成:              一个类主要分为几个部分:分别是类的定义(类的继承,接口的实现),全局变量方法,属性,内部类等. 第一点: 实现的接口 public fin ...