学习目标:
python学习十、
学习内容:
1、类和实例
2、访问权限
3、继承和多态
4、获取对象信息
5、实例属性和类属性
1、类和实例
类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同
1、创建类:class + 类名
class+类名,如Student,类名通常是大写开头的单词,后面再跟(),()中表示该类是从哪个类继承下来的,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类
class Student(object):
pass
变量bart就是一个指向Student的实例,后面的0x10a67a590是内存地址,每个object的地址都不一样,而Student本身则是一个类,可以自由地给一个实例变量绑定属性
class Student(object):
pass
a = Student()
print(a)
a.name = 'Bob'
print(a.name)
输出:
<__main__.Student object at 0x00000284C8201C40>
Bob
2、定义一个如__init__特殊的方法,在创建实例的时候,就把一些特定的特殊属性绑到实例中去,意思就是当类在实例化的过程中,__init__方法(函数)可以直接被执行
特殊方法“_特殊方法_”前后分别有两个下划线!!!
第一个参数永远是self,表示创建的实例本身,表示各种属性绑定到实例本身
有了实例的特殊方法就不要再传空值了,必须传入特殊方法对应的值,self不用传
class Student(object):
def __init__(self,name,manger,score):
self.name = name
self.manger = manger
self.score = score
Math = Student('Bob', 'man', 99)
print(Math.name)
print(Math.manger)
print(Math.score)
输出:
Bob
man
99
3、数据封装
- 面向对象的编程最重要的就是数据封装
- 在类中,每个实例都拥有各自的相关参数的数据,我们可以通过创建内部函数函数来访问这些数据,这样就把数据封装在类的内部了
- 在类的内部创建的函数,访问类内部的数据能与类形成关系,我们就说这些函数时类的方法
class Student(object):
def __init__(self,name,manger,score):
self.name = name
self.manger = manger
self.score = score
def pull(self):
print('%s %s %s' %(self.name,self.manger,self.score))
Math = Student('Bob', 'man', 99)
Student.pull(Math)
输出:
Bob man 99
- 调用类的方法
class House_money(object):
def __init__(self, rent, water, electric_bill):
self.rent = rent
self.water = water
self.electric_bill = electric_bill
def disburse(self):
expenditure = 1200
count = 0
count = self.rent + self.water+self.electric_bill
print('本月总花销:%s 元' %count)
if expenditure > count:
print('本月花销还剩:%s 元'% (expenditure - count))
else:
print('本月花销超出:%s 元'% (count - expenditure))
a = House_money(800,66,120)
a.disburse()
输出:
本月总花销: 986 元
本月花销还剩: 214 元
class Student(object):
def __init__(self,name,manger,score):
self.name = name
self.manger = manger
self.score = score
def pull(self):
print('%s %s %s' %(self.name,self.manger,self.score))
def grader(self):
if self.score>90:
return 'A'
elif self.score>=60:
return 'B'
else:
return 'C'
Bob = Student('Bob', 'man', 99)
Bob.pull()
print(Bob.score,Bob.grader())
print(Bob.grader())
输出:
Bob man 99
99 A
A
2、访问权限
类里面有属性和方法,外部代码可以通过调用实例变量的方法来操作数据,把外部代码限制不让外部代码访问类里的变量,就需要将变量改成私有变量
想要变量只让内部访问,,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private)
- 当我们用外部的代码访问变量时,会显示无法访问
class Dormitory(object):
def __init__(self, name, manger, classes):
self.__name = name
self.__manger = manger
self.__classes = classes
def people(self):
print('%s:%s:%s' %(self.__name, self.__manger, self.__classes))
a = Dormitory('Bob','male',1)
a.__name
输出:
Traceback (most recent call last):
File "F:/pycharm/project/test.py", line 11, in <module>
a.__name
AttributeError: 'Dormitory' object has no attribute '__name'
- 如果想要外部代码访问到内部变量则设置get方法
class Dormitory(object):
def __init__(self, name, manger, classes):
self.__name = name
self.__manger = manger
self.__classes = classes
def get_name(self):
return self.__name
def get_manger(self):
return self.__manger
def get_classes(self):
return self.__classes
- 如果有想要外部代码能设置内部变量则设置set方法
class Dormitory(object):
def __init__(self, name, manger, classes):
self.__name = name
self.__manger = manger
self.__classes = classes
def set_person(self, name, manger, classes):
ban = []
if manger == 'male'and classes == 1:
ban.append(name)
return ban
- 实例:把gender隐藏起来,用get和set方法实现外部代码的调用
class Student(object):
def __init__(self, name, gender):
self.name = name
self.__gender = gender
def get_gender(self):
return self.__gender
def set_gender(self,gender):
self.__gender =gender
bart = Student('Bart', 'male')
if bart.get_gender() != 'male':
print('测试失败!')
else:
bart.set_gender('female')
if bart.get_gender() != 'female':
print('测试失败!')
else:
print('测试成功!')
3、继承和多态
面向对象编程中,定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)
1、创建一个继承类
继承可以直接使用父类的所有功能,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写
- 首先编写一个父类:
父类里面包含一个run的方法
class Animal(object):
def run(self):
print('Animal is running...')
再次编写一个类并继承这个父类,子类会完全继承父类的属性和方法
class Dog(Animal):
pass
class Cat(Animal):
pass
dog = Dog()
dog.run()
cat = Cat()
cat.run()
输出:
Animal is running...
Animal is running...
子类也可以拥有自己的方法,当子类的方法与父类的方法同名时,直接调用子类的方法
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('the dog is running...')
class Cat(Animal):
def eat(self):
print('the cat is eating...')
dog = Dog()
dog.run()
cat = Cat()
cat.eat()
输出:
the dog is running...
the cat is eatting...
2、多态
类似于python的其他数据类型,list、dict、str,class所编写的类也是一种数据类型
用isinstance()可以判断变量是什么数据类型
- 可以看出c不仅是Dog类型,还是Animal类型
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('the dog is running...')
class Cat(Animal):
def eat(self):
print('the cat is eating...')
c=Dog()
print(isinstance(c,Dog))
print(isinstance(c,Animal))
输出:
True
True
- 多个子类继承了父类,函数在调用类型时只管接收父类型就行,只要是父类或者是子类都可以调用父类中的方法,这就是多态
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('the dog is running...')
class Cat(Animal):
def eat(self):
print('the cat is eating...')
def run_twice(animal):
animal.run()
animal.run()
class Tortoise(Animal):
def run(self):
print('Tortoise is running slowly...')
run_twice(Tortoise())
- 静态语言和动态语言
- Java就是静态语言,必须传入父类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法
- python这样的动态语言,不一定分要传入父类类型,有一个父类的方法就行了
4、获取对象信息
1、type()函数
判断一般的对象类型
print(type(123))
print(type('123'))
输出:
<class 'int'>
<class 'str'>
import types
def fn():
pass
print(type(fn)==types.FunctionType)
print(type(abs)==types.BuiltinFunctionType)
print(type(lambda x: x)==types.LambdaType)
print(type((x for x in range(10)))==types.GeneratorType)
输出:
True
True
True
True
2、isinstance()函数
class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数
class Animal(object):
def run(self):
print('Animal is running...')
class Dog(Animal):
def run(self):
print('the dog is running...')
class Cat(Animal):
def eat(self):
print('the cat is eating...')
d=Dog()
print(isinstance(d,Dog))
print(isinstance(d,Animal))
print(isinstance(d, Dog) and isinstance(d, Animal))
输出:
True
True
True
- isinstance也可以判断变量是某些类型中的一种
isinstance([1, 2, 3], (list, tuple))
True
3、使用dir()函数
- 获得一个对象的所有属性和方法
print(dir('ABC'))
输出:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__...]
- getattr()、setattr()以及hasattr(),可以操作一个对象的状态
class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
obj = MyObject()
print(obj.x)
print(hasattr(obj, 'y'))# 有属性'y'吗?
print(setattr(obj, 'y', 19)) # 设置一个属性'y'
print(getattr(obj, 'y')) # 获取属性'y'
输出:
9
False
None
19
5、实例属性和类属性
Python是动态语言,根据类创建的实例可以任意绑定属性
1、绑定变量
- 给实例绑定属性
通过实例变量,或者通过self变量给实例绑定属性
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')
s.score = 90
- 给类绑定属性
直接在class中定义属性,这种属性是类属性,该类的所有实例都可以使用这个属性
class Student(object):
name = 'Student'
本文围绕Python编程展开,介绍了类和实例的创建、访问权限设置、继承和多态特性、获取对象信息的方法以及实例属性和类属性的绑定。如创建类时可指定继承类,通过特殊方法绑定属性,用双下划线设置私有变量,多态让函数调用更灵活。
2424





