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. 新霸哥带你轻松玩转Oracle数据库

    接触过软件开发的朋友可能都会知道oracle,在开发的过程中,数据存储都可能会用到oracle的,因为oracle具有处理速度快,安全级别特别的高.但是有一个缺点就是比较的贵,只有一个大型的公司才有可 ...

  2. linux新建用户并分配sudo权限

    新建用户 useradd [username] 给用户设置密码 passwd [username] 设置sudo权限 首先将sudoers权限设置可写入 chmod u+w /etc/sudoers ...

  3. “12306”是如何支撑百万QPS的?

    来源:掘金 作者:绘你一世倾城 链接:https://juejin.im/post/5d84e21f6fb9a06ac8248149 秒杀系统的艺术 12306抢票,极限并发带来的思考? 每到节假日期 ...

  4. JavaNIO

    Java New IO 简称 nio,在jdk1.4提供了新的api,有如下特性: 1.为所有原始类型提供缓存支持 2.字符集编解码解决方案 3.Channel:新的原始io抽象 4.支持锁和内存映射 ...

  5. 将临时全局表中的符合字段导入test数据库中

    --表1 开户级别表 insert into test.dbo.crm_m_cust_summary(CUST_CERT_N O,ASSETAMT_GRADE_CD)select cust_no,cu ...

  6. C++与C#对于引用外部文件成员使用的区别

    对于C++控制台项目,如果有两个.cpp的文件都想引用同一个类的成员时,我们可以定义一个类,然后在类的头文件中添加extern来修饰. Box.cpp如下: #include "Box.h& ...

  7. BZOJ - 1036 树的统计Count (LCT)

    LCT试炼题(代码量居然完爆树剖?) #include<bits/stdc++.h> using namespace std; ,inf=0x3f3f3f3f; ],flp[N],n,m, ...

  8. CSS札记(二):级联与继承

    一.级联 概念:级联(The cascade),CSS是Cascading Style Sheet的简写,说明级联是非常重要的.从表层来看,级联表明CSS规则的顺序问题,但是级联远比这个复杂,在所有的 ...

  9. 基于element ui 实现七牛云自定义key上传文件,并监听更新上传进度

    借助上传Upload 上传组件的 http-request 覆盖默认的上传行为,可以自定义上传的实现 <el-upload multiple ref="sliderUpload&quo ...

  10. java数据结构--array与ArrayList的区别

    ArrayList 内部是由一个array 实现的. 如果你知道array 和 ArrayList 的相似点和不同点,就可以选择什么时候用array 或者使用ArrayList , array 提供 ...