#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/8/17 11:18
# @Author :
# 使用type() 获取对象类型
print(type(123))
print(type("123"))
print(type(None))
print(type(abs))
print(type('123') == str)
import types
def fnc():
pass
print(type(fnc) == types.FunctionType) # 是否是自建函数
print(type(abs) == types.BuiltinFunctionType) # 是否是内建函数
print(type(abs) == types.BuiltinMethodType) # 是否是内建方法
print(type(lambda x: x) == types.LambdaType) # 是否是lambda函数
print(type((x for x in range(100) if x % 2 == 0)) == types.GeneratorType) # 是否是生成器类型
# 使用isinstance() 判断类型
# 对于父子继承的类型使用type()不好判断
class A:
def __init__(self):
pass
class B(A):
def __init__(self):
pass
class C(B):
def __init__(self):
pass
a = A()
b = B()
c = C()
print(isinstance(a, A)) # ====>True
print(isinstance(a, B)) # ====>False
print(isinstance(b, A)) # ====>True
# 能用type()判断的基本类型也可以用isinstance()判断:
print(isinstance([1, 23, 4, 5], (list, tuple))) # ==>true
# 使用dir() 获取一个对象的所有属性和方法,可以使用dir函数
print(dir("ABC"))
# 类似__xxx__的属性和方法在Python中都是有特殊用途的,比如__len__方法返回长度。实际len()函数可能就是调用的这个__len__方法
# __init__ 对象的初始化方法(也称之为构造函数)
# getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:
class Person:
def __init__(self, name, age):
self.name = name # 没有私有
self.__age = age # 设置了私有
p = Person("小白", 20)
print(hasattr(p, 'age')) # ==> False 判断p对象是否有age这个属性 因为age设置了私有化
print(hasattr(p, 'name')) # ==> True 判断p对象是否有name这个属性 这个没有设置私有化 所有有这个属性
print(getattr(p, 'name')) # ==> '小白'
setattr(p, 'name', '小黑') # ==> 设置属性name 为小黑
print(getattr(p, 'name')) # ==>变成了小黑
# 如果试图获取不存在的属性,会抛出AttributeError的错误:
# getattr 也可以设置默认值 ,当获取不到值得时候 同样 getattr也可以获取对象的方法
# 实例属性 和 类属性
# 我们可以在类定义以后,或者对象实例化以后动态给他们绑定属性和方法
# 这样做的话 我们后面会很难维护
# 这个时候我们可以通过__slots__属性限定动态绑定属性和方法
class Student(object):
__slots__ = ('name', 'age') # 用tuple 定义语序绑定的属性名称
s = Student()
s.name = '小白'
s.age = 20
# s.score =99 #绑定属性score 此时会报错
# 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
# 在绑定属性的时候,如果我们直接把属性暴露出去,虽然简单,但是没办法检查参数 ,导致可以把成绩随便修改
s.age = 220
# 这时候 我们可能会通过set_score和get_score来设置和获取数据 同时定义__score为私有属性
# 但是上面的方法略显复杂 ,同样 python内置一个装饰器 @property 可以把一个方法变成属性 调用
class Employer(object):
@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score mast be an integer')
if value < 0 or value > 1000:
raise ValueError('score must between 0 and 100')
self._score = value
e = Employer();
e.score =90
print(e.score)
# e.score = 'er' # 会报错
# e.score =2222 # 依然会报错
# 还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性:
# 请利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution:
class Screen(object):
@property
def width(self):
return self._width
@width.setter
def width(self,value):
if not isinstance(value,int):
raise ValueError('width mast be integer')
self._width =value
@property
def height(self):
return self._height
@height.setter
def height(self,value):
if not isinstance(value,int):
raise ValueError('height mast be integer')
self._height =value
@property
def resolution(self):
return '竖屏'
sc =Screen()
sc.width =1000
sc.height =600
# sc.resolution ='12' #会报错 该属性没有设置setter的方法
print(sc.width)
print(sc.height)
print(sc.resolution)