title: python中的类
data: 2018-4-4
categories:
- 类别
tags: - 标签
__metaclass__ = type
class Person:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
def color(self, color):
print('%s is %s' % (self.name, color))
(1)新式类
__metaclass__ = type
,意味着下面的类是新式类(在python3以前的称之为旧式类,这里不讨论什么新式旧式)
(2)定义类
创建了一个叫"Persion“的类,这里就不废话了。。。
(3)初始化
def __init__()
这个函数比较特殊,叫做初始化函数(有的书上也会称之为构造函数,但 __new__()
才是真的构造)
通过 Person 创建一个实例对象:girl = Person('xuyuling')
传递一个参数xuyuling
girl 是Person类的一个实例对象,它Person类有属性和方法。。。。
使用对象的属性:girl.name
调用对象的方法:girl.getName()
def __init__(self, *args):
pass
不一定每次都要从外部传入参数,可以在函数参数中设置默认值
class Person:
def __init__(self, name, lang='python', website='youif.cn'):
self.name = name
self.lang = lang
self.website = website
p1 = Person('张三')
p2 = Person('李四', lang='java', website='www.baidu.com')
print('p1name=', p1.name)
print('p2name=', p2.name)
print('p2lang=', p2.lang)
print('p1Web=', p1.website)
print('p2Web=', p2.website)
输出:
---------------- p1name= 张三 p2name= 李四 p2lang= java p1Web= youif.cn p2Web= www.baidu.com ----------------------
self 的作用
类的函数里面,第一个参数是 self ,而且不能省略。但在实例化的时候,这个参数不需要写,也不需要为这个参数传值。
以前面的”Person“类为例,在 Person 实例化的过程总 girl = Person('xuyuling'),字符串’xuyuling'通过初始化函数(init)的参数已经存入到内存中,并且是以 Person 类型,组成了一个对象,这个对象和变量 girl 建立引用关系。
self 其实也是一个实例,这个实例与上面的 girl 一样,也有属性。
上述代码中:self.name = name, 就是规定了 self 实例的一个属性,这个是属性的名字也叫 name,且属性的值等于初始化函数的参数 name 所导入的数据。
注意,self.name 中的 name 和初始化函数的参数 name 没有任何关系,它们两个一样。当然,如果写出 self.xyz = name,也是可以的。
当然,self 的属性数据,也不一定非得由参数传入,可以在构造函数中设定。例如:
__metaclass__ = type
class Person:
def __init__(self, name):
self.name = name
self.email = "xxx@qq.com" #这个属性不是通过参数传递的
info = Person('zhong')
print('inofName=', info.name)
print('ifoEmail=', info.email)
输出结果:
---------------- inofName= zhong ifoEmail= xxx@qq.com ----------------------
继承
__metaclass__ = type
class Person:
def speak(self ):
print('hello world!')
def setHeight(self):
print('一米八')
def setWeight(self, n):
print('My weight is :', n)
class Girl(Person):
def setHeight(self):
print('一米六')
if __name__ == '__main__':
xu = Girl()
xu.setHeight()
xu.speak()
xu.setWeight(90)
输出结果:
---------------- 一米六 hello world! My weight is : 90 --------------------
首先,定义了一个 Person 类,在这个类里面定义了三个方法。注意,没有定义初始化函数,初始化函数在类中不是必须的。
然后有自定义了一个 Girl 类,这个类后面的括号里面是一个类的名字,这句以为着 Girl 类继承了 Person 类。因此 Girl 类就有了 Person 中的全部方法和属性。
如果子类中有父类中相同的方法名,那么,执行的执行的是子类的方法,这样叫做重写。
多重继承
__metaclass__ = type
class Person:
def eye(self):
print('two eyes')
def height(self, n):
print("一米八")
class Girl:
age = 20
def color(self):
print('The girl is white')
class HotGirl(Person, Girl):
pass
if __name__ == '__main__':
kong = HotGirl()
kong.eye()
kong.height(90)
kong.color()
print(kong.age)
输出:
-------------------- two eyes 一米八 The girl is white 20 -------------------------
多重继承的顺序
class A1(object):
def foo(self):
print("A1-foo")
class A2(object):
def foo(self):
print('A2-foo')
def color(self):
print('A2-color')
class B1(A1, A2):
pass
class B2(A1, A2):
def color(self):
print('M2-color')
class H(B1, B2):
pass
if __name__ == '__main__':
print(H.__mro__)
s = H()
s.foo()
s.color()
输出:
(<class '__main__.H'>, <class '__main__.B1'>, <class '__main__.B2'>, <class '__main__.A1'>, <class '__main__.A2'>, <class 'object'>)
A1-foo
M2-color
代码总的print(G.__mro__)
是要打印出类的继承顺序。
即 H --> B1 --> B2 --> A1 --> A2
对继承属性和方法搜索的顺序称之为“广度优先”。