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. Servlet监听器——实现在线登录人数统计小例子

    一.概念 servlet监听器的主要目的是给web应用增加事件处理机制,以便更好的监视和控制web应用的状态变化,从而在后台调用相应处理程序. 二.监听器的类型 1.根据监听对象的类型和范围,分为3类 ...

  2. iOS 支付 [支付宝、银联、微信]

    这是开头语 前不久做了一个项目,涉及到支付宝和银联支付,支付宝和银联都是业界的老大哥,文档.SDK都是很屌,屌的找不到,屌的看不懂,屌到没朋友(吐槽而已),本文将涉及到的最新可用SDK.文档,以及本人 ...

  3. JVM内存分配和垃圾回收以及性能调优

    JVM内存分配策略 一:堆中优先分配Eden 大多数情况下,对象都在新生代的Eden区中分配内存.而新生代会频繁进行垃圾回收. 二:大对象直接进入老年代 需要大量连续空间的对象,如:长字符串.数组等, ...

  4. redis常见问题和解决方案

    转载:https://www.cnblogs.com/aspirant/p/6820262.html [原创]那些年用过的Redis集群架构(含面试解析) redis常见问题和解决方案 持久化.主从问 ...

  5. kafka消费之kafka查看topic是否有数据

    通过原生kafka,查看对应的topic是否有数据 下载kafka:登录Apache kafka官方下载 http://kafka.apache.org/downloads.html 配置config ...

  6. SpringBoot封装自己的Starter

    https://juejin.im/post/5cb880c2f265da03981fc031 一.说明 我们在使用SpringBoot的时候常常要引入一些Starter,例如spring-boot- ...

  7. TypeError: Cannot read property 'splice' of undefined

    splice是删除数组里的项,报这个错证明你点前面那个并不是个数组,仔细一看,还真是数组名称写错了

  8. Python修炼之路-数据类型

    Python编程之列表 列表是一个使用一对中括号"[   ]" 括起来的有序的集合,可以通过索引访问列表元素,也可以增加和删除元素. 列表的索引:第一个元素索引为0,最后一个元素索 ...

  9. HDU-2444-The Accomodation of Students(二分图判定,最大匹配)

    链接: https://vjudge.net/problem/HDU-2444#author=634579757 题意: There are a group of students. Some of ...

  10. HTML5基础——笔记

    HTML5基础——笔记 近几年来,互联网+.大数据.云计算‘物联网‘虚拟现实‘人工智能.机器学习.移动互联网等IT相关新名词.新概念层出不穷,相关产业发展如火如荼.互联网+移动互联网已经深入到人民日常 ...