判断一个对象是不是属于某一类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了判断一个对象是不是属于某一类相关的知识,希望对你有一定的参考价值。

参考技术A javascript中检测对象的类型的运算符有:typeof、constructor、instanceof。

typeof:typeof是一个一元运算符,经常用来检测一个变量是不是最基本的数据类型,返回结果是一个说明运算数类型的字符串。如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在)。 但 typeof 的能力有限,其对于Date、RegExp、Array类型返回的都是"object"。所以它只在区别对象和原始类型的时候才有用。要区一种对象类型和另一种对象类型,必须使用其他的方法。

instanceof 运算符:用来判断某个构造函数的 prototype 属性所指向的对象是否存在于另外一个要检测对象的原型链上。简单说就是判断一个引用类型的变量具体是不是某种类型的对象,instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。

如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。instanceof方法可以判断变量是否是数组类型。

constructor 属性: JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。

如何使用 constructor 属性:

输出:

Object.prototype.toString.call():该方法是目前为止发现的判断一个对象类型的最好的办法。

面向对象高级

1.isinstance与issubclass  

  在介绍反射之前,先来介绍两个关于类的内置方法,第一个是用来判断对象是否是某一类的对象(以前常说的判断是否是某一类型,类与类型其实是一个概念),第二个则是用来判断某一类是否是继承了另一个类

l=list([1,2,3])
print(isinstance(l,list)) #True
class People:
   def __init__(self):
       pass
class Chinese(People):
   def __init__(self):
       pass
print(issubclass(Chinese,People))#True
#两者用法一致,均是将判断的对象与对象可能是某一类型作为第一第二参数传入

2.反射(反省)

  先来给反射下一个定义:反射就是通过字符串来操作python代码中的变量,函数,甚至类与方法,(如何去理解这句话呢,试想我们如果想让打印机打印,是不是要给它一个打印的指令呢,现在如果说你必须通过输入的形式去直接命令计算机,让计算机能理解你输入的字符串到底是对应什么操作,关键在于我们提供input输入的都是字符串,而计算机是无法直接识别字符串的),那就要介绍反射中的四小龙了,

1.hasattr 判断一个变量是否能够加点调用一个名字,返回值为True 或 False

 

class Foo:
   x=1
   def __init__(self):
       pass
   def tell(self):
       print(‘from tell‘)
print(hasattr(Foo,‘x‘))

2.getattr 直接获取一个变量中的名字的值

 

class Foo:
   x=1
   def __init__(self):
       pass
   def tell(self):
       print(‘from tell‘)
obj=Foo()
getattr(obj,‘tell‘)() #from tell

3.setattr

 

class Foo:
   x=1
   def __init__(self):
       pass
   def tell(self):
       print(‘from tell‘)
obj=Foo()
print(Foo.x) #1
setattr(Foo,‘x‘,11)
print(Foo.x)#11

4.delattr

 

class Foo:
   x=1
   def __init__(self):
       pass
   def tell(self):
       print(‘from tell‘)
obj=Foo()
print(Foo.x) #1
delattr(Foo,‘x‘)
print(Foo.x) #AttributeError: type object ‘Foo‘ has no attribute ‘x‘

  总结:上面这四个方法需要注意的地方有以下几点:1.括号里面的传入的前后参数之间,肯定是可以加点再加名字的形式调用(也就是说,只要是设计到通过点加名字就可以调用的形式,都可以转化成上面这四种方式去操作,比如:导入模块后应用模块中的名字,类中属性方法的调用等),2.传入的参数中要寻找的参数必须是以字符串的形式的传入,咋一看好像这种方式更加复杂,但是恰恰相反,请看例子

class People:
   country=‘China‘
   def __init__(self,name):
       self.name=name
   def tell(self):
       print(‘from tell‘)
   def check(self):
       print(‘from check‘)
p1=People(‘jby‘)
cmd=input(‘please input your cmd‘).strip()
if hasattr(p1,cmd):
   getattr(p1,cmd)()

  这样我们就可以直接将用户输入的字符串直接反射到对应的名字身上,从而直接调用~

 

 

 

3.类的内置方法补充

__ str __

__ del __

__ call __(调用)

 exec(),eval()

  1.str 在对象,在遇到被打印的情况下,自动触发~

 

class People:
   def __init__(self,name,age,sex):
       self.name=name
       self.age=age
       self.sex=sex
   def __str__(self):#__str__内置方法,遇到print自动触发返回字符串格式类型的数据(可自己定制)
       return ‘<name:%s,age:%s,sex:%s>‘%(self.name,self.age,self.sex)
l=list([1,2,3])#用list类产生的对象为什么在打印的时候会直接打印对象里面包含的所有值而不是内存地址原因就是内部有__str__方法
print(l)
p1=People(‘alex‘,73,‘male‘)
print(p1)

  2.del 在对象被删除的情况下(在对象被删除之前)自动触发(这里的删除可以是主动删除也可能是程序执行完毕,回收资源删除)

 

class Myopen:
   def __init__(self,filename,mode=‘r‘,encoding=‘utf-8‘):
       self.filename=filename
       self.mode=mode
       self.encoding=encoding
       self.f=open(filename,mode=mode,encoding=encoding)
       #这里的open申请了系统资源,在程序关闭时应用程序会回收自己资源,但是系统资源没有被回收
   def __str__(self):
       return ‘%s‘%self.f.read()
   def __del__(self):
       #这里的__del__会在对象被删除之前(被系统回收),执行将系统资源先回收了
       #所有__del__主要用于设计到回收资源这块的应用
       print(‘正在删除系统资源‘)
       self.f.close()
file=Myopen(‘settings.py‘)
print(file)

  3.call 在对象被调用的情况下,自动触发

 

class Foo:
   def __init__(self):
       pass
   def __str__(self):
       return ‘aaa‘
   def __del__(self):
       pass
   def __call__(self, *args, **kwargs):#(调用对象时就会自动触发此方法的执行将对象当作第一个参数传给self,将对象括号内的参数传给args和kwargs)
       print(‘执行了__call__‘,args,kwargs)
?
obj=Foo()
obj(1,2,3,a=2,b=3,c=1)#执行了__call__ (1, 2, 3) {‘a‘: 2, ‘b‘: 3, ‘c‘: 1}

 

 

4.exec运行字符串中的代码,放入全局名称空间或局部名称空间

globalsdic = {}
localsdic = {}
?
exec("""
aaaaaaaaaaaaaaaaaaaa = 1
bbbbbbbbbbbbbbbbbbbbbbbbbbbb = 2
def func1():
  print("我是func1")
""",globalsdic,localsdic)
?
?
# 如果同时制定了 全局和局部 则 会字符串中包含名称 解析后存到局部中
# print(globalsdic)
print(localsdic)
localsdic["func1"]()

exec(‘xxxxx‘,{},{})有三个参数第二个是全局名称空间,第三个是局部名称空间,只要没使用global定义,就默认存放在局部名称空间

 

exec(‘xxxxx‘,{},{})有三个参数第二个是全局名称空间,第三个是局部名称空间,只要没使用global定义,就默认存放在局部名称空间

 

 

 

区别:

exec():其作用 是帮你解析执行python代码 并且将得到的名称 存储到制定的名称空间

 

eval():计算指定表达式的值。也就是说它要执行的python代码只能是单个表达式**(注意eval不支持任何形式的赋值操作),而不能是复杂的代码逻辑

 

 

 

 

































































































以上是关于判断一个对象是不是属于某一类的主要内容,如果未能解决你的问题,请参考以下文章

KNN(k-Nearest Neighbor)算法

面向对象高级

JavaScript--判断某个变量是不是数组

js中如何判断一个属性是不是属于某个对象

Java求助:如何判断某对象是不是存在?如果不存在,创建该对象

反射与元类