语法格式:
class ClassName:
#属性
[属性定义体]
#方法
[方法定义体]
#属性就是变量,静态的特征,方法就是一个个的函数,通过这些函数来描述动作行为。
类对象实例化
对象名 = 类名()
>>> car = Car()
注意,类名后面要添加一个括号“()”。
调用对象的属性和方法
对象名.属性名
对象名.方法名
>>> car.infor()
在Python中,可以使用内置方法isinstance()
来测试一个对象是否为某个类的实例。
>>> isinstance(car, Car)
True
>>> isinstance(car, str)
False
__ init __(self)
只要实例化一个对象的时候,这个方法就会在对象被创建的时候自动调用。实例化对象的时候是可以传入参数的,这些参数会自动传入__ init __(self,param1,param2,…)
方法中,我们可以通过重写这个方法来自定义对象的初始化操作。
举例
>>> class Bear:
def __init__(self,name):
self.name = name
def kill(self):
print("%s,是保护动物,不能杀..."% self.name)
>>> a = Bear('狗熊')
>>> a.kill()
狗熊,是保护动物,不能杀...
另外,我们还可以把传入的参数设置为默认参数,我们在实例化的时候不传入参数系统也不会报错。
>>> class Bear:
def __init__(self,name = "默认的熊"):
self.name = name
def kill(self):
print("%s,是保护动物,不能杀..."% self.name)
__ init __()
中定义的,定义在方法中的变量,属于某个具体的对象,定义和使用时必须以self作为前缀;class Car:
price = 100000 #定义类属性
def __init__(self, c):
self.color = c #定义实例属性
__ dict __
属性每个类和对象都有一个叫作__ dict __
的字典属性,用来记录该类或对象所拥有的属性。用类名调用输出该由类中所有类属性组成的字典;而使用类的实例对象输出由类中所有实例属性组成的字典。Python内置类型不支持属性的增加,用户自定义类及其对象一般支持属性和方法的增加与删除。
class Car: #通过类调用类属性
price = 100000 #定义类属性
def __init__(self, c):
self.color = c #定义实例属性
>>>car1 = Car("Red")
>>> print(car1.__dict__)
{'color': 'Red'}
>>> car1 = Car("Red") #实例化对象
>>> car2 = Car("Blue")
>>> print(car1.color) #查看实例属性的值
Red
>>> car1.color = "Yellow" #修改实例属性
>>> print(car2.color) #
Blue
>>> print(car1.color)
Yellow
>>> car1.age=1 #增加实例属性
>>> print(car1.age) #查看实例属性的值
1
>>> del Car.name '#删除类属性
>>> Car.name
Traceback (most recent call last)
Python并没有对私有属性提供严格的访问保护机制。
class A:
def __init__(self, value1 = 0, value2 = 0):
self.value1 = value1
self.__value2 = value2
def setValue(self, value1, value2):
self.value1 = value1
self.__value2 = value2
def show(self):
print(self.value1)
print(self.__value2)
def printt(self):
print(self.__value2)
a=A()
a.printt()#内部访问
print(a._A__value2)#外部访问,不能直接访问私有属性
在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。
_xxx
:受保护属性,不能用’from module import *'导入;__ xxx __
:系统定义的特殊属性;__ xxx
:私有属性,只有类对象自己能访问,子类对象不能直接访问到这个属性,但在对象外部可以通过“对象名.类名__ xxx
”这样的特殊方式来访问。class Root:
__total = 0
def __init__(self, v): #构造方法
self.__value = v
Root.__total += 1
def show(self): #普通实例方法
print('self.__value:', self.__value)
print('Root.__total:', Root.__total)
def __private(self): #私有方法
print(‘This is a private function.’)
>>> r._Root__private()
This is a private function.
如果通过类名来调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的数据属性。
class Root:
__total = 0
def __init__(self, v): #构造方法
self.__value = v
Root.__total += 1
def show(self): #普通实例方法
print('self.__value:', self.__value)
print('Root.__total:', Root.__total)
r = Root(3)
rr = Root(5)
#试图通过类名直接调用实例方法,失败
>>> Root.show()
TypeError: unbound method show() must be called with Root instance as first argument (got nothing instead)
#但是可以通过这种方法来调用方法并访问实例属性
>>> Root.show(r)
self.__value: 3
Root.__total: 2
#通过类名调用实例方法时为self参数显式传递对象名
>>> Root.show(rr)
self.__value: 5
Root.__total: 2
@classmethod
。第一个参数必须是当前类对象,该参数名一般约定为“cls”
,通过它来传递类的属性和方法(不能传实例的属性和方法), 并且在调用类方法时不需要为该参数传递值。@staticmethod
。可以没有参数,没有“self”和“cls”
参数。实例对象和类对象都可以调用。class Root:
__total = 0
def __init__(self, v): #构造方法
self.__value = v
Root.__total += 1
def show(self): #普通实例方法
print('self.__value:', self.__value)
print('Root.__total:', Root.__total)
@classmethod #修饰器,声明类方法
def classShowTotal(cls): #类方法
print(cls.__total)
@staticmethod #修饰器,声明静态方法
def staticShowTotal(): #静态方法
print(Root.__total)
>>> r = Root(3)
>>> r.classShowTotal() #对象来调用类方法
1
>>> r.staticShowTotal() #对象来调用静态方法
1
>>> r.show()
self.__value: 3
Root.__total: 1
>>> rr = Root(5)
>>> Root.classShowTotal() #类名调用类方法
2
>>> Root.staticShowTotal() #类名调用静态方法
2
例题
自定义栈,实现基本的入栈、出栈,判栈空,栈满操作。
class Stack:
def __init__(self, size = 10):
'''创建栈对象并进行初始化,默认栈大小为10'''
# 使用列表存放栈的元素
self._content = [] # 初始栈大小
self._size = size # 栈中元素个数初始化为0
self._current = 0
def empty(self):
'''清空栈'''
self._content = []
self._current = 0
def isFull(self):
'''测试栈是否已满'''
return self._current == self._size
def push(self, v):
'''将新元素入栈'''
# 模拟入栈,需要先测试栈是否已满
if self._current < self._size:
self._content.append(v)
# 栈中元素个数加1
self._current = self._current+1
else:
print('Stack Full!')
def pop(self):
'''将栈顶元素出栈'''
# 模拟出栈,需要先测试栈是否为空
if self._content:
# 栈中元素个数减1
self._current = self._current-1
return self._content.pop()
else:
print('Stack is empty!')
__ init __()
,一般用来为数据属性设置初值或进行其他必要的初始化工作,在创建对象时被自动调用和执行。如果用户没有设计构造函数,Python将提供一个默认的构造函数用来进行必要的初始化工作。__ del __()
,一般用来释放对象占用的资源,在Python删除对象和收回对象空间时被自动调用和执行。如果用户没有编写析构函数,Python将提供一个默认的析构函数进行必要的清理工作class Person(object):
def run(self):
print("run")
def eat(self, food):
print("eat" + food)
def __init__(self,name,age,height,weight):
self.name=name
self.age=age
self.height=height
self.weight=weight
def __del__(self):#当程序结束时运行
print("析构函数")
#在函数里定义的对象,会在函数结束时自动释放,这样可以减少内存空间的浪费
>>>per1=Person("lili",20,175,50)
>>>del per1 #手动释放对象
析构函数
>>>print(per1.name)#释放对象后程序不运行
继承是子类自动共享父类的数据和方法的机制。
语法格式如下:
Class ClassName(BaseClassName):
……
ClassName:是子类的名称,第一个字母必须大写。
BaseClassName:是父类的名称。
派生类可以继承父类的公有属性,但是不能继承其私有属性。如果需要在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式来实现这一目的。
class A:
#构造方法可能会被派生类继承
def __init__(self):
self.__private()
self.public()
#私有方法在派生类中不能直接访问
def __private(self):
print('__private() method in A')
#公开方法在派生类中可以直接访问,及被覆盖
def public(self):
print('public() method in A')
class B(A):
#类B没有构造方法,会继承基类的构造方法
def __private(self): #不会覆盖基类的私有方法
print('__private() method in B')
#覆盖了继承自A类的公开方法public
def public(self):
print('public() method in B')
>>> b = B() #自动调用基类构造方法
__private() method in A
public() method in B
>>> dir(b) #基类和派生类的私有方法访问方式不一样
['_A__private', '_B__private',...]
>>> b._A__private()
__private() method in A
#dir( ):不仅仅输出本类中新添加的属性名和方法,还会输出从父类继承得到的属性名和方法名。
>>> class C(A):
def __init__(self): #显式定义构造函数
self.__private() #这里调用的是类C的私有方法
self.public()
def __private(self):
print('__private() method in C')
def public(self):
print('public() method in C')
>>> c = C() #调用类C的构造方法
__private() method in C
public() method in C
>>> dir(c)
['_A__private', '_C__private', '__class__', ...]
>>> class Animal(object): #定义基类
def show(self):
print('I am an animal.')
>>> class Cat(Animal): #派生类,覆盖了基类的show()方法
def show(self):
print('I am a cat.')
>>> class Dog(Animal): #派生类
def show(self):
print('I am a dog.')
>>> class Tiger(Animal): #派生类
def show(self):
print('I am a tiger.')
>>> class Test(Animal): #派生类,没有覆盖基类的show()方法
pass
>>> x = [item() for item in (Animal, Cat, Dog, Tiger, Test)]
>>> for item in x: #遍历基类和派生类对象并调用show()方法
item.show()
I am an animal.
I am a cat.
I am a dog.
I am a tiger.
I am an animal.