使用type在对象方法中调用类方法
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在对象方法中调用类方法的更多相关文章
- Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)
Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...
- Java中对象方法的调用过程&动态绑定(Dynamic Binding)
Java面向对象的最重要的一个特点就是多态, 而多态当中涉及到了一个重要的机制是动态绑定(Dynamic binding). 之前只有一个大概的概念, 没有深入去了解动态绑定的机理, 直到很多公司都问 ...
- Java-main方法中调用非static方法
java的calss中,在public static void main(String[] args) { }方法中调用非static的方法:在main方法中创建该calss的对象,用对象调用非sta ...
- springMVC在普通方法中调用service方法
SpringContextUtil类 package com.common.util; import org.springframework.beans.BeansException;import o ...
- JAVA Main方法中调用非静态方法
在JAVA中静态方法中只能调用其他,静态方法.main方法都是静态方法,如果想调用其它的方法,要么只能是其它的静态方法.还有一种方法就是将当前类实例化在调用它的非静态方法 public class t ...
- 动态的创建Class对象方法及调用方式性能分析
有了Class对象,能做什么? 创建类的对象:调用Class对象的newInstance()方法 类必须有一个无参数的构造器. 类的构造器的访问权限需要足够. 思考?没有无参的构造器就不能创建对象吗? ...
- 为什么Java中 wait 方法需要在 synchronized 的方法中调用?
另一个棘手的核心 Java 问题,wait 和 notify.它们是在有 synchronized 标记的方法或 synchronized 块中调用的,因为 wait 和 modify 需要监视对其上 ...
- JS高级 —— 普通函数、构造函数、对象方法的调用
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- javascript中string对象方法中的slice、substring、substr的区别联系
1.slice.substring.snustr均属于String的对象方法,用于截取或提取字符串片段,三者均布破坏原先的字符串,而是以新的字符串返回被提取的部分. <script> va ...
随机推荐
- LeetCode 338. 比特位计数
338. 比特位计数 题目描述 给定一个非负整数 num.对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回. 示例 示例 1: 输入: 2 输出 ...
- Action访问Servlet的API
Action访问Servlet的API_,主要访问如下: 1.>获取request对象 2.>获取请求参数 3.>获取response对象,可用于传递cookie 3.>获取作 ...
- 高效开发之使用Cmder替换cmd
一.为什么要更换为cmder 在做项目时,有些时候我想复制控制台上面的代码时,cmd有的时候复制粘贴很麻烦,Cmder则不会,并且Cmder可以分屏多开窗口,可以设置窗口颜色,字体大小,并且很多快捷键 ...
- python-装饰器2
python-装饰器2 1.函数既“变量 def bar(): print("in the bar") def foo(): print("in the foo" ...
- SpringBootMVC01——A simple SpringBootMVC Sample
不带数据库的SpringBootMVC案例 1.创建一个SpringBoot项目,添加thymeleaf,webstarter 2.目录层级 3.启动器代码 package com.littlepag ...
- w、who、last、lastbon、lastlog显示登录命令用法
一.w 显示已登录用户信息和用户正在执行命令 1.命令功能 w可以显示已登录系统的用户,并显示用户正在执行的命令 2.语法格式 w option user 选项说明 选项 选项说明 -h 不显示前两行 ...
- Spring框架几种创建bean的方式
Spring框架下,Bean的创建和装配非常的灵活,提供了三种主要的方式,并且相互见可以互相看见,也就是你可以随意地采用你喜欢且合适的方式创建Bean,而不用担心他们之间的兼容问题. 一.使用XML显 ...
- MYSQL利用merge存储引擎来实现分表
创建user1和user2两个分表 建表语句如下:只是表名不一样,其他字段信息及主键一致. CREATE TABLE IF NOT EXISTS user1( id INT(11) NOT NUL ...
- 【Python系列】Python自动发邮件脚本
缘起 这段时间给朋友搞了个群发邮件的脚本,为了防止进入垃圾邮件,做了很多工作,刚搞完,垃圾邮件进入率50%,觉得还不错,如果要将垃圾邮件的进入率再调低,估计就要花钱买主机了,想想也就算了,先发一个月, ...
- 【BZOJ 3681】Arietta
传送门 题目描述 Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中. 但是她从未停止过和恋人 Velding 的书信往来.一天,她准备去探访他. 对着窗外的阳光,临 ...