一、判断对象是否属于类、判断类是否派生自某个类

class Zero:passclass One(Zero):passclass Two(One, Zero):pass# 判断对象是否完全是某个类
print(type(Two()) == Two)#true
print(type(Two()) == Zero)#false
# 判断对象是否属于某个类
print(isinstance(Two(), Zero))#true
# 判断某个类是否是另一个类的子类
print(Zero in Two.__bases__)#true
print(issubclass(Two,Zero))

二、关于元类

在Python中,类型分为三个层次:元类、类、对象。
类是元类的实例化,对象是类的实例化。
在Python中,元类、类、对象三种东西相当于结点,它们之间的有向边表示继承关系。整个类型系统构成一个有向无环图。这个有向无环图分为三层,一个对象可以继承多个类。

metaclass的作用就是创建类
举一个小例子

class BaseMetaClass(type):def __new__(cls, *args, **kwargs):kind = type.__new__(cls, *args, **kwargs)print(kind)return kindclass Base(metaclass=BaseMetaClass):passclass One(Base):passclass Two(Base):pass

输出为

<class '__main__.Base'>
<class '__main__.One'>
<class '__main__.Two'>

在此例中,只进行了类的声明,没有进行类的实例化。在进行类的声明过程中,会调用metaclass的new方法,new方法的返回值就是一个具体的类型。类型是特殊的对象。
Python中,内置函数type起的作用非常关键,它具有两个作用

  • type(obj)查看obj的类型,type(cls)查看cls的元类
  • type(className,*arg,*karg)构造函数产生新的类

在上述代码的基础上加几句话

class Three:pass
print(type(One))#<class '__main__.BaseMetaClass'>
print(type(Three))#<class 'type'>
print(type(type))#<class 'type'>

三、一切皆type

在Java中,一切皆是Object
在Python中,一切皆是type

def f():passff = lambda: 0
x = []
for i in (list, dict, type, f, ff, x):while type(i) != i:print(i, end=' ')i = type(i)print(i)

输出为

<class 'list'> <class 'type'>
<class 'dict'> <class 'type'>
<class 'type'>
<function f at 0x000000CEE01B7F28> <class 'function'> <class 'type'>
<function <lambda> at 0x000000CEE07E5A60> <class 'function'> <class 'type'>
[] <class 'list'> <class 'type'>

四、函数中可以定义类,类中可以定义函数

函数是function类型,function是type类型

>>> def choose_class(name):
…       if name == 'foo':
…           class Foo(object):
…               pass
…           return Foo     # 返回的是类,不是类的实例
…       else:
…           class Bar(object):
…               pass
…           return Bar
…
>>> MyClass = choose_class('foo')
>>> print MyClass              # 函数返回的是类,不是类的实例
<class '__main__'.Foo>
>>> print MyClass()            # 你可以通过这个类创建类实例,也就是对象
<__main__.Foo object at 0x89c6d4c>

五、使用type定义类型

type(类型名称,基类列表,属性字典)

A = type("A", (), {'name': 'weidiao','age': 23,'__str__': lambda self: '{},{}'.format(self.name, self.age)
})
x = A()
print(x)#输出为weidiao,23

六、__class__属性

__class__属性时是每一种类型必然包含的属性,该属性的取值相当于x.__class==type(x)

七、不要忘记python是一门脚本语言

下面定义了一个类A,它有name和age两个属性,但是我可以随意给这个对象添加属性。

A = type("A", (), {'name': 'weidiao','age': 23,'__str__': lambda self: '{},{},{}'.format(self.name, self.age,self.baga)#如果没有baga属性,此处会报错
})
x = A()
x.baga='3'
print(x)

八、调用父类构造函数的两种方法

在Java和C++中,子类的构造函数都会自动调用父类的构造函数。
在Python中,子类是不会自动调用父类的构造函数的,因为在Python中没有构造函数,而只有初始化函数!而初始化函数只相当于普普通通的函数,所以,这就需要我们手动来调用父类的构造函数。
首先来看,如果不调用父类构造函数会出现什么情况

class A:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return self.name + str(self.age)class B(A):def __init__(self):passb = B()
print(b)

在此例中,B类没有调用A类的初始化函数,所以B类就缺少了name和age属性,B类的str相当于A类的str,print时就会因为缺少name和age属性报错

AttributeError: 'B' object has no attribute 'name'

有两种方法调用父类的构造函数

class A:def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return self.name + str(self.age)class B(A):def __init__(self):# A.__init__(self,'weidiao',23)super(B,self).__init__('weidiao',23)b = B()
print(b)

这两种方法第一种方法比较灵活,完全可以取代第二种方法。
A.__init__(self,args)这种方式只初始化了父类A
super(B,self).__init__(self,args)这种方式初始化了第一个父类(根据继承的顺序),所以这种方式是完全可以用FirstFather.__init()进行取代的。

九、单例

Java中的对象的创建和对象的初始化这两个过程是紧密耦合在一起的,对象创建过程指的是为对象分配必要的内存空间,对象初始化指的是向内存中写入值。简言之,Java中一旦调用构造函数,对象空间开辟和对象初始化两种操作就同时完成了。在Java中,单例只创建一次且只初始化一次。
在Python中不是这样,Python中对象创建过程和对象初始化过程是分开的。class的__new__()函数负责对象的创建,class的__init__()负责对象的初始化。在Python中,单例可能创建一次,初始化多次。

下面看一种单例的写法:

class Dog:dog = Nonedef __new__(cls, *args, **kwargs):if cls.dog is None:cls.dog = object.__new__(cls)print('create singleton over')return cls.dogdef __init__(self, name):print('init is called')self.name = name# 下面这句话会报错,因为Dog.dog目前为None
# print(Dog.dog.name)
x = Dog('x')
y = Dog('y')
print(x.name)  # y
print(y.name)  # y

此例中,会发现init is called输出两次,但是x和y实际上是同一个对象。也就是说,在Python中,只要调用对象的构造函数,必然会先调用__new__()函数,__new__()返回一个对象,然后Python会自动调用返回对象的__init__()函数。

上面例子的另一种实现是把重写new函数的工作放到一个父类里面,这样就能够实现:只需要继承父类就能够让自己变成单例。

class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = object.__new__(cls)return cls._instanceclass Dog(Singleton):def __init__(self, name):self.name = namex = Dog('x')
y = Dog('y')
print(x.name, y.name)

在Python中,我们创建的任何一个对象,无需重写setattr方法即可随便往对象上“悬挂”成员变量。

class Ha:passx = Ha()
x.dog = 3
print(x.dog)

单例的实现

from functools import lru_cacheclass Singleton:@lru_cache()def __new__(cls, *args, **kwargs):obj = object.__new__(cls)obj.inited = Falsereturn objclass Haha(Singleton):def __init__(self, name):if self.inited:returnself.inited = Trueself.name = nameprint("inited")x = Haha("x")
y = Haha("y")
print(x.name)
print(y.name)

总结

在语言的完美、统一程度上,Python无人可及,Java都比它差一点。

转载于:https://www.cnblogs.com/weiyinfu/p/8086504.html

Python面向对象几个知识点相关推荐

  1. 关于python面向对象编程中、下列说法中_关于Python面向对象编程的知识点总结

    前言 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程. 接下来我们 ...

  2. python 完全面向对象_史上最全的Python面向对象知识点疏理

    原标题:史上最全的Python面向对象知识点疏理 面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变 ...

  3. python 打印对象的全部属性_详解:Python 面向对象静态方法、类方法、属性方法知识点小结...

    今天为大家带来的内容是介绍了Python 面向对象静态方法.类方法.属性方法,总结分析了Python 面向对象程序设计中静态方法.类方法.属性方法相关概念.知识点.操作技巧与使用注意事项,需要的朋友可 ...

  4. Python面向对象知识点详解(含__init__、__add__、__str__、issubclass()、isinstance()等方法的使用)

    Python面向对象 创建类 类属性与方法 `__init__()` 类的构造函数(初始化方法) 类的继承 方法重写 基础重载方法 `__str__( self )`的使用 运算符重载 `__add_ ...

  5. python开发需要掌握哪些知识-学习Python应该掌握哪些知识点?

    原标题:学习Python应该掌握哪些知识点? 当你想要进入一个全新的领域时,首先要弄清楚的就是它的体系.那么在Python领域,应该掌握哪些知识点呢? Python基础与高级编程 1.Linux环境搭 ...

  6. python 面向对象(进阶篇)

    上一篇<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个" ...

  7. 其实python面向对象3分钟就可以入门(14)

    本系列文章将会以通俗易懂的对话方式进行教学,对话中将涵盖了新手在学习中的一般问题.此系列将会持续更新,包括别的语言以及实战都将使用对话的方式进行教学,基础编程语言教学适用于零基础小白,之后实战课程也将 ...

  8. python面向对象编程的语言_怎么使用python面向对象编程

    怎么使用python面向对象编程 发布时间:2020-08-25 13:42:19 来源:亿速云 阅读:89 作者:Leah 本篇文章给大家分享的是有关怎么使用python面向对象编程,小编觉得挺实用 ...

  9. python面向对象的特征_03 Python 关键点讲解:面向对象的机制

    本节开始讲解量化交易系统最基本的编程工具 Python 的关键知识点.我们经过调研发现,目前市面上量化交易相关的书籍.课程等教学产品多数从最基础的安装.语法.函数-开始介绍 Python 这个工具,我 ...

最新文章

  1. python读取.edf文件
  2. f1 score 代码_2019JDATA-用户对品类下店铺的购买预测方案及代码分享(亚军)
  3. 蓝桥杯算法训练_2的次幂表示+前缀表达式+Anagrams问题+出现次数最多的整数
  4. Mongodb数据库(1.mongodb的介绍(非关系型数据库)下载与安装(Windows10))
  5. linux su和sudo命令的区别
  6. .gitignore失效 无法忽略node_modules问题
  7. css32D、3D、动画、过渡
  8. 简单理解机器学习中的L1距离,L2距离,L-Inf距离
  9. Cloud Foundry 在 Azure 中国正式发布
  10. DNS解析错误解决办法
  11. 如何使用火狐下的两款接口测试工具RESTClient和HttpRequester发送post请求
  12. 软件开发过程模型综述
  13. 外卖返利小程序源码下载 美团/饿了么小程序源码下载
  14. 大数据分析:原著 PK 电影,谁更得观众心?
  15. LFI获取WENSHELL
  16. 初生牛犊不怕虎:年轻人的成长之路
  17. 【洛谷】P1359 租用游艇
  18. 线性回归:自相关检测及其处理方法
  19. NUC980开源项目40-PLC远程下载/内网穿透(非技术)
  20. 通用技术课件_优化—让我们做得更好 | 高中通用技术优质课展示

热门文章

  1. Linux 查看dns运行状态
  2. Quartz.NET的使用(附源码)
  3. 使用phpqrcode来生成二维码/thinkphp
  4. 诗歌rails之Hacking ActiveRecord
  5. Linux下搭建mysql主从服务器
  6. mongodb查询优化
  7. vnpy2.0安装后报错ModuleNotFoundError: No module named 'vnpy.api.ctp.vnctpmd'
  8. virmach主机购买和使用
  9. CTA策略07_MultiTimeframeStrategy
  10. 报表人的福音!25个实用报表模板合集,适用多个业务场景