一、类和实例
- 定义一个类
- 定义类的关键字: class
- 所有定义的类会自动继承于object这个类
class Student(object):
pass
- 类的初始化方法
class Student(object):
'__init__ 初始化方法, 当有定义有__init__方法时,创建类实例时会自动反射获取该方法进行初始化 ; 有点像java中的构造方法'
def __init__(self, name, age):
self._name = name
self._age = age
- 定义变量
- 类中的public变量命名方式:xxx 规范的命名变量就是public的。
- 私有变量private : __xxx ; 在变量前添加双下划线
- 定义函数的访问权限与变量一样
class Student(object):
profession = 'Student' # 定义一个公开变量,职业; 所有的实例都可以访问
__name = None # 私有变量, 外界不可直接访问
__age = None
二、获取对象的信息
- type() 返回对象的类型
a = 'abcc'
print(type(a))
- isinstance() 也是判断变量的类型
# 判断a变量是否时str或int类型
print(isinstance(a, (str, int)))
- dir() 获得一个对象的所有属性和方法,
print(dir(str))
- len() 获取对象的长度
- 自定义对象返回长度的方法; 注意xxx这样的变量或函数在Python中都是有特殊用途的
class MyDog(object):
# 以下的方法是在对象使用len()方法是返回对象的长度为100
def __len__(self):
return 100
print(len(MyDog())) # 结果为100
- getattr()、setattr()以及hasattr() 获取属性、设置属性和判断是否有该属性的方法
class Test(object):
_name = 'test'
def test(self):
print('test function')
t = Test()
# 判断类Test是否有_name属性
print('class Test has _name attr ', hasattr(t, '_name'))
# 设置类Test的属性_name
setattr(t, '_name', 'test132465')
# 打印类Test的属性_name
print(getattr(t, '_name'))
三、继承与多态
- python 支持多重继承
# 继承的写法
#父类 1
class class1(object):
pass
#父类 2
class class2(object):
pass
#子类1 继承父类1 和 2
class subclass1(class1,class1):
pass
- 多态
# 这里定义一个工厂的类,用来喂养动物的
class FeedingFactory(object):
# 在没有用多态时,每喂养一种动物,则需要定义特定的方法
def feed_dog(self):
print('dog feed raw')
def feed_cat(self):
print('cat feed fish')
# 使用多态后,可以之定义一种喂养的方法,无论喂多少种动物都不需要更改此方法
def feed(self, animate):
print('%s feed %s' % (animate.__getattribute__('_name'), animate.__getattribute__('_food')))
factory = FeedingFactory()
dog = Dog('dog', 'raw')
cat = Cat('cat', 'fish')
factory.feed(dog)
factory.feed(cat)
四、面向对象高级
- 限制该class实例能添加的属性:
- python是动态语言,可以才类创造后任务绑定变量和函数
- 特殊的slots变量,来限制该class实例能添加的属性:
- 注意:使用slots要注意,slots定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
class Student(object):
pass
# 为Studnet类绑定name属性, 通过实例绑定的变量或函数只能本实例能访问到
s = Student();
s.name = 'abc'
print(s.name)
s2 = Student()
# print(s2.name) # 会抛出异常: AttributeError: 'Student' object has no attribute 'name'
# 为了让全部的实例能绑定变量或函数,可以通过类来绑定
Student.age = 12 # 有类Student创建的实例都有age属性绑定
s3 = Student()
print('the age of s3 is ', s3.age)
- 装饰器 @property
- Python内置的@property装饰器就是负责把一个方法变成属性调用的:
- 注意:属性和方法名不要相同,否则后导致不断的调用自身而没有设终止条件而栈溢出
class Student(object):
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
@property
def score(self):
return self.score
'使用@property的好处是:可以在变量赋值时,对变量进行约束检查'
@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 between 0 ~ 100!')
self.score = value
s = Student()
s.name = '123'
print(s.name)
s.score = 60 # OK,实际转化为s.set_score(60)
s.score # OK,实际转化为s.get_score()