面向对象最重要的概念就是类(Class)和实例(Instance)。
类是具有相同特性的一类事物,是抽象的模板。
实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
类
类定义
最简单的类定义看起来像这样:
class ClassName:
<statement-1>
.
.
.
<statement-N>
类对象
类对象支持两种操作:属性引用和实例化
属性引用
属性引用使用的标准语法: obj.name。 有效的属性名称是类对象被创建时存在于类命名空间中的所有名称。
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
那么 MyClass.i 和 MyClass.f 就是有效的属性引用,将分别返回一个整数和一个函数对象。
实例化
类的 实例化 使用函数表示法。 可以把类对象视为是返回该类的一个新实例的不带参数的函数。
x = MyClass()
创建类的新 实例 并将此对象分配给局部变量 x。
构造方法__init__(self,arg)
实例化操作(“调用”类对象)会创建一个空对象。为此类定义可能包含一个名为 init() 的特殊方法,类的实例化操作会自动为新创建的类实例发起调用 init()。
类和实例变量
一般来说,实例变量用于每个实例的唯一数据,而类变量用于类的所有实例共享的属性和方法:
示例一:
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
d=Dog('rubi')
e=Dog('bili')
print(d.kind)
print(d.name)
print(e.kind)
print(e.name)
执行结果
以下代码中的 tricks 列表不应该被用作类变量,因为所有的 Dog 实例将只共享一个单独的列表
示例二:
class Dog_f:
tricks = [] # mistaken use of a class variable,共有属性不应该为列表,因为多个实例赋值会修改同一个内容
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
d=Dog_f('rubi')
e=Dog_f('bili')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks) #['roll over', 'play dead']
执行结果:
可以明显的看到tricks列表的内容因为两个实例而出现了不应该的内容。
正确的类设计应该使用实例变量:
示例三:
class Dog_t:
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
d=Dog_t('rubi')
e=Dog_t('bili')
d.add_trick('roll over')
e.add_trick('play dead')
print(d.tricks)
执行结果:
补充说明
- 如果同样的属性名称同时出现在实例和类中,则属性查找会优先选择实例:
- 方法可以通过与普通函数相同的方式引用全局名称。 与方法相关联的全局作用域就是包含其定义的模块。 (类永远不会被作为全局作用域。)
- 方法可以通过使用 self 参数的方法属性调用其他方法:
示例四:
class Bag:
def __init__(self):
self.data = []
def add(self, x):
self.data.append(x)
def addtwice(self, x):
self.add(x)
self.add(x)
练习
个人情况输出:
class person:
def __init__(self,n,a,g,h,w):
self.name=n
self.age=a
self.gender=g
self.height=h
self.weight=w
def show(self):
print("个人情况".center(50,"-"))
print("姓名: %s"%self.name)
print("年龄: %s"%self.age)
print("性别: %s"%self.gender)
# print("身高: %s"%self.height)
# print("体重: %s"%self.weight)
print("身高: %scm 体重: %skg"%(self.height,self.weight))
n_01=person("Rose",18,"female",178,75)
n_01.show()
执行后:
总结
类是面向对象最重要的部分,还有很多需要注意的地方,可以在后面的学习过程中逐步完善。
- self 参数可以想象成类自身会好理解一点。