Python练习task10:类与对象
对象 = 属性 + 方法
类主要定义对象的结构,我们通过类的模板来创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。
封装
封装是一种信息隐蔽技术。我们定义类可以使用关键字 class,后面紧跟类的名称、冒号和类的实现。
class Cat:
#属性
color='white'
leg=4
weight=10
sound='meow'
#方法
def eat(self):
print('I like eating fish')
def play(self):
print('I like playing with balls')
def drink(self):
print('I like drinking milk')
t=Cat()
print(t)
print(type(t))
print(t.__class__)
print(t.__class__.__name__)
t.eat()
t.play()
t.drink()
print(type(Cat))
继承
继承是子类自动共享父类之间数据和方法的机制。
class List(list):
pass
t=List([3,8,6,10,2])
t.append(9)
t.sort()
print(t)
多态
不同对象对同一方法响应不同的行动。
class Animal:
def run(self):
raise AttributeError('子类必须实现这个方法')
class People(Animal):
def run(self):
print('People is walking')
class Turtle(Animal):
def run(self):
print('Turtle is crawling')
class Dog(Animal):
def run(self):
print('Dog is running')
def func(animal):
animal.run()
func(People())
self
Python 的 self 相当于 C++ 的 this 指针。self代表类的实例,而非类。
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
从上面的例子中可以很明显的看出,self代表的是类的实例。而self.__class__则指向类。
Python的魔法方法
Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切。他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。
class Dog:
def __init__(self, name):
self.name=name
def kick(self):
print("我是%s,我会发出汪汪的声音" % self.name)
a=Dog("柴犬")
b=Dog("哈士奇")
c=Dog("金毛")
c.kick()
公有和私有
在 Python 中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。
class JustCounter:
__secretCount = 0
publicCount = 0
def count(self):
self.__secretCount += 1
self.publicCount += 1
print(self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter._JustCounter__secretCount)
print(counter.__secretCount)
class Site:
def __init__(self,name,age):
self.name=name
self.__age=age
def who(self):
print('name:',self.name)
print('age:',self.__age)
def __foo(self):
print('这是私有方法')
def foo(self):
print('这是公共方法')
self.__foo()
x=Site('MengZhou', '29')
x.who()
x.foo()
x.__foo()
继承
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
比如,我们已经编写了一个名为Animal的class,有一个run()方法可以直接打印:
class Animal(object):
def run(self):
print('Animal is running...')
当我们需要编写Dog和Cat类时,就可以直接从Animal类继承:
class Dog(Animal):
pass
class Cat(Animal):
pass
对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类。Cat和Dog类似。
继承有什么好处?最大的好处是子类获得了父类的全部功能。由于Animial实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()方法:
dog = Dog()
dog.run()
cat = Cat()
cat.run()
无论是Dog还是Cat,它们run()的时候,显示的都是Animal is running…,符合逻辑的做法是分别显示Dog is running…和Cat is running…,因此,对Dog和Cat类改进如下:
class Dog(Animal):
def run(self):
print('Dog is running...')
class Cat(Animal):
def run(self):
print('Cat is running...')
当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。
组合
class Turtle:
def __init__(self, x):
self.num = x
class Fish:
def __init__(self, x):
self.num = x
class Pool:
def __init__(self, x, y):
self.turtle = Turtle(x)
self.fish = Fish(y)
def print_num(self):
print("水池里面有乌龟%s只,小鱼%s条" % (self.turtle.num, self.fish.num))
p = Pool(1,10)
p.print_num()
类、类对象和实例对象
类对象:创建一个类,其实也是一个对象也在内存开辟了一块空间,称为类对象,类对象只有一个。
class A(object):
pass
实例对象:就是通过实例化类创建的对象,称为实例对象,实例对象可以有多个。
a = A()
b = A()
c = A()
类属性:类里面方法外面定义的变量称为类属性。类属性所属于类对象并且多个实例对象之间共享同一个类属性,说白了就是类属性所有的通过该类实例化的对象都能共享。
class A():
a = xx #类属性
def __init__(self):
A.a = xx
实例属性:实例属性和具体的某个实例对象有关系,并且一个实例对象和另外一个实例对象是不共享属性的,说白了实例属性只能在自己的对象里面使用,其他的对象不能直接使用,因为self是谁调用,它的值就属于该对象。
class 类名():
__init__(self):
self.name = xx #实例属性
类属性和实例属性区别
类属性:类外面,可以通过 实例对象.类属性 和 类名.类属性 进行调用。类里面,通过 self.类属性 和 类名.类属性 进行调用。
实例属性 :类外面,可以通过 实例对象.实例属性 调用。类里面,通过 self.实例属性 调用。实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。
注意:属性与方法名相同,属性会覆盖方法。
绑定
Python 严格要求方法需要有实例才能被调用,这种限制其实就是 Python 所谓的绑定概念。Python 对象的数据属性通常存储在名为.__ dict__的字典中,我们可以直接访问__dict__,或利用 Python 的内置函数vars()获取.__ dict__。
一些内置函数
issubclass(class, classinfo) 方法用于判断参数 class 是否是类型参数 classinfo 的子类。
一个类被认为是其自身的子类。
classinfo可以是类对象的元组,只要class是其中任何一个候选类的子类,则返回True。
class A:
pass
class B(A):
pass
print(issubclass(B, A))
print(issubclass(B, B))
print(issubclass(A, B))
print(issubclass(B, object))
isinstance(object, classinfo) 方法用于判断一个对象是否是一个已知的类型,类似type()。但是他们的区别在于type()不会认为子类是一种父类类型,不考虑继承关系,而isinstance()会认为子类是一种父类类型,考虑继承关系。如果第一个参数不是对象,则永远返回False。如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。
class A:
pass
class B(A):
pass
print(isinstance(A(), A))
print(type(A()) == A)
print(isinstance(B(), A))
print(type(B()) == A)
hasattr(object, name)用于判断对象是否包含对应的属性。
class Coordinate:
x = 1988
point1 = Coordinate()
print(hasattr(point1, 'x'))
print(hasattr(point1, 'no'))
getattr(object, name[, default])用于返回一个对象属性值。
class A(object):
bar = 1
a = A()
print(getattr(a, 'bar'))
print(getattr(a, 'bar2', 3))
print(getattr(a, 'bar2'))
setattr(object, name, value)对应函数 getattr(),用于设置属性值,该属性不一定是存在的。
class A(object):
bar = 1
a = A()
print(getattr(a, 'bar')) # 1
setattr(a, 'bar', 5)
print(a.bar) # 5
setattr(a, "age", 28)
print(a.age) # 28
delattr(object, name)用于删除属性。
另外还有几种内置函数:
class property([fget[, fset[, fdel[, doc]]]])用于在新式类中返回属性值。
fget – 获取属性值的函数。
fset – 设置属性值的函数。
fdel – 删除属性值函数。
doc – 属性描述信息。
下一篇: 打印回形数组