1.获取对象信息
(1)使用type():判断对象类型,返回对应的class类型
print type(123) # int
print type('yj') # 字符串
print type(True) # 布尔值
print type(None)
print type(abs) # 函数
#输出信息
<type 'int'>
<type 'str'>
<type 'bool'>
<type 'NoneType'>
<type 'builtin_function_or_method'>
# 具体这种的没弄清楚啥意思
# 判断一个对象是否是函数,使用types模块中定义的变量
import types
def fn():
pass
print type(fn) == types.FunctionType # True
(2)使用isinstance():class的继承关系,一种对象是否是某种类型
class Animal(object):
def run(self):
print('Animal is running......')
class Dog(Animal):
def run(self):
print('Dog is running......')
class Happy(Dog):
def run(self):
print('Happy is running......')
animal = Animal()
dog = Dog()
happy = Happy()
print isinstance(happy, Happy) # True
print isinstance(happy, Dog) # True 由于继承
print isinstance(happy, Animal) # True 由于继承
print isinstance(dog, Dog) # True
print isinstance(dog, Animal) # True 由于继承
能用type()判断的基本类型也可以用isinstance()判断
isinstance(123, int) # True
isinstance('yj', str) # True
判断一个变量是否是某些类型中的一种
print isinstance([1,2,3], (list, tuple)) # True
(3)使用dir():获得一个对象的所有属性和方法,返回一个包含字符串的list
print dir('ABC')
在Python中,调用len()获取一个对象的长度,实际上,在len()函数内部,他自动调用该对象的__len__()
print len('ABC')
print 'ABC'.__len__()
这两个结果是等价的
(4)自己写类,使用len(),就自己写一个__len__()
class MyName(object):
def __len__(self):
return 50
myName = MyName()
print len(myName) # 50
这样仅仅是把属性和方法列出来 配合getattr()/setattr()/hasattr(),可以直接操作一个对象的状态
class MyName(object):
def __init__(self):
self.x = 9
def double(self):
return self.x * self.x
myName = MyName()
测试该对象的属性:
print hasattr(myName,'x') # True
print hasattr(myName,'y') # False
print setattr(myName,'y',10)
print hasattr(myName,'y') # True
print getattr(myName,'y')
print myName.y
获取属性的时候可以传入一个default,如果属性不存在,就返回默认值
print getattr(myName,'z',404) # 404
获取对象的方法
print hasattr(myName,'double')
print getattr(myName,'double')
2.实例属性和类属性
Python是动态语言,根据类创建的实例可以任意绑定属性
(1)给实例绑定属性:通过实例变量,或者通过self变量
class Student(object):
def __init__(self,name,age):
self.name = name
self.age = age
yj = Student('YJ',24)
print yj.name
print yj.age
(2) class类本身绑定属性:直接在class中定义属性,称为类属性,归class类所有
类属性,类的所有实例都可以访问到
class Student(object):
name = 'LP'
student = Student()
print student.name # 实例没有name属性,所以打印类属性
print Student.name # 类属性
student.name = 'YJ' # 实例绑定name属性
print student.name # 实例属性优先级高于类属性,打印实例属性
print Student.name
del student.name
print student.name # 打印类属性
PS: Python中,不要把实例属性和类属性使用相同的名字, 因为实例属性的优先级较高,相同名称的实例属性和类属性将屏蔽掉类属性, 但是删除实例属性之后,再使用相同的名称,访问到的是类属性
3.面向对象高级编程——多重继承、定制类、元类
(1)使用__slots__
1)给实例绑定方法
class Student(object): # 声明一个类
pass
yj = Student() # 给实例绑定属性
yj.name = 'YJ'
print yj.name
def set_age(self,age): # 给实例绑定方法
self.age = age
from types import MethodType
yj.set_age = MethodType(set_age, yj)
yj.set_age(24) # 调用方法
print yj.age
lp = Student() # 但是,给一个实例绑定的方法,对另一个实例是不起作用的
lp.set_age()
2)给class绑定方法
class Student(object): # 给class绑定方法,所有的实例都可以调用
pass
def set_score(self, score):
self.score = score
Student.set_score = set_score
yj = Student()
yj.set_score(100)
print yj.score
lp = Student()
lp.set_score(101)
print lp.score
3)使用__slots__
Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性
class Student(object):
__slots__ = ('name','age')
lz = Student()
lz.name = 'LZ'
print lz.name
lz.age = 24
print lz.age
lz.score = 99 # 报错
PS: __slots__定义的属性仅仅是对当前实例起作用,对机场的子类不起作用
class Student(object):
__slots__ = ('name','age')
lz = Student()
lz.name = 'LZ'
print lz.name
lz.age = 24
print lz.age
class GradeStudent(Student):
pass
grade = GradeStudent()
print grade.age # 报错
PS: 子类允许定义的属性 = 自身的__slots__+父类的__slots__
(2)使用@property
- 普通的get/set
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer')
if value < 0 or value > 100:
raise ValueError('score must be between 0~100')
self._score = value
yj = Student() # 声明实例方法
yj.set_score(99)
print yj.get_score()
yj.set_score(101) # 报错
2)使用@property。
装饰器(decorator)可以给函数添加功能。
Python内置的@property装饰器:把一个方法变成属性调用。
class Student(object):
@property # 读
def score(self):
return self._score
@score.setter # 写
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer')
if value < 0 or value > 100:
raise ValueError('score must be between 0~100')
self._score = value
lp = Student()
lp.score = 99 # 等价于 lp.set_score(99)
print lp.score
lp.score = 101 # 报错
3)定义只读属性:只定义getter,不定义setter
class Student(object):
@property # 读
def birth(self):
return self._birth
@birth.setter # 写
def birth(self, value):
self._birth = value
@property # 读
def age(self):
return 2015 - self._birth
lp = Student()
lp.birth = 24
print lp.birth
print lp.age
#birth可读可写;age只读。
4)一个作业
class Screen(object):
@property # 读
def width(self):
return self._width
@width.setter # 写
def width(self, value):
self._width = value
@property # 读
def height(self):
return self._height
@height.setter # 写
def height(self, value):
self._height = value
@property # 读
def resolution(self):
return self._height + self._width
screen = Screen()
screen.width = 100
screen.height = 200
print screen.width
print screen.height
print screen.resolution