在Python
中,一切皆是对象。
1. 快速入门 1.1 定义类 文件位置: basis/classdemo.py
class Person (object ): def __init__ (self, name, age ): self.name = name self.age = age def say (self ): content = "我是{},今年{}岁" .format (self.name, self.age) print (content)
1.2 类代码说明
1.3 创建对象 from basis import classdemo if __name__ == "__main__" : p1 = classdemo.Person("张三" , 18 ) p1.say() print ("p1.name" , p1.name) print ("p1.age" , p1.age)
1.4 代码说明
from basis import classdemo
: 指的从模块basis
导入classdemo
这个包;
classdemo.Person
: 基于类创建对象;
p1.say()
: 访问成员方法
p1.name 和 p1.age
: 访问成员属性;
2. 构造函数 在Python
中的构造函数使用特殊的方法名__init__
来定义,它位于类的内部。当创建一个类的实例时,会自动调用该类的构造函数,并传递必要的参数。
格式: def __init__(self, *args)
@注意:当__init__
定义几个参数,实例化时,就需要传几个参数,除非原参数有默认值,否则会报错
2.1 没有默认值 class Person (object ): def __init__ (self, name, age ): self.name = name self.age = age ... p1 = Person() Traceback (most recent call last): File "/Users/liuqh/ProjectItem/PythonItem/python-learn-demo/main.py" , line 6 , in <module> p1 = classdemo.Person() ^^^^^^^^^^^^^^^^^^ TypeError: Person.__init__() missing 2 required positional arguments: 'name' and 'age'
2.2 有默认值 class Person (object ): def __init__ (self, name="张三" , age=19 ): self.name = name self.age = age ... p1 = Person()print ("p1.name" , p1.name)print ("p1.age" , p1.age)
3. 访问权限 3.1 公有属性 有时为了确保类内的属性的安全,我们是不希望外部直接访问或者修改类的属性信息;如下面简单示例:
class Bank : def __init__ (self, amount ): self.amount = amount def use_money (self, useAmount ): self.amount = self.amount - useAmount print ("花掉:{},剩余金额:{}" .format (useAmount, self.amount)) from basis import bankif __name__ == "__main__" : b = bank.Bank(100 ) b.use_money(10 ) b.amount = 10 b.use_money(10 )
上面示例演示充值100,花了两次10元,因为外部可以直接修改类属性,最后发现余额变成0元;
3.2 私有属性 在Python
中没有关键字public(代表公有)、private(代表私有)
,如果想定义私有属性,直接在属性名称前面增加__
(2个底线),就变成了私有属性; 修改上面示例:
class Bank : def __init__ (self, amount ): self.__amount = amount def use_money (self, useAmount ): self.__amount = self.__amount - useAmount print ("花掉:{},剩余金额:{}" .format (useAmount, self.__amount)) from basis import bankif __name__ == "__main__" : b = bank.Bank(100 ) b.use_money(10 ) b.__amount = 10 b.use_money(10 )
从上面示例可以看出,虽然在外边修改私有属性,但是从输出结果可以看出:修改并未生效
3.3 私有方法 在python
中默认方法都是可以直接在外边访问,如果想定义私有方法,也是直接在方法名称前面增加__
(2个底线),就变成了私有方法; 如下面示例:
class Bank : def __init__ (self, amount ): self.__amount__ = amount def __add_money (self, amount ): self.__amount__ += amount from basis import bankif __name__ == "__main__" : b = bank.Bank(100 ) b.__add_money(10000 ) Traceback (most recent call last): File "/Users/liuqh/ProjectItem/PythonItem/python-learn-demo/main.py" , line 7 , in <module> b.__add_money(10000 ) ^^^^^^^^^^^^^ AttributeError: 'Bank' object has no attribute '__add_money' . Did you mean: '_Bank__add_money' ?
@注意:强制访问私有方法会直接报错。
4. 继承 Python
属于面向对象的编程语言,面向对象中的继承,可以直接让我们复用父类的一些方法;
4.1 单继承 class People : def __init__ (self, name, age ): self.name = name self.age = age def say (self ): print ("姓名:{} 年龄:{}" .format (self.name, self.age))class Body (People ): def say (self ): print ("我叫{},今年{}岁,是个帅气的男孩" .format (self.name, self.age))class Girl (People ): pass from basis import peopleif __name__ == "__main__" : body = people.Body("王麻子" , 38 ) girl = people.Girl("张小丽" , 18 ) body.say() girl.say()
从上面示例可以看出,继承父类后,可以直接复用父类中公有的属性(name、age
)和方法(say()
)。也可以在自己类中覆盖父类的方法,如Body
类重新实现say()
方法。
4.2 多继承 Python
和其他语言对比,特殊的一点是,Python
中的类支持多继承;多继承一般都会让人有个疑问: 如果同时继承多个父类,并且都存在一样的方法名,子类会调用哪个父类的方法呢?`
class People : def __init__ (self, name, age ): self.name = name self.age = ageclass Body (People ): def say (self ): print ("我叫{},今年{}岁,是个帅气的男孩" .format (self.name, self.age))class Girl (People ): def say (self ): print ("我叫{},今年{}岁,是个漂亮的女孩" .format (self.name, self.age))class Programmer (Body, Girl): pass from basis import peopleif __name__ == "__main__" : it = people.Programmer("张飞" , 88 ) it.say()
@注:如果同时继承多个父类,并且存在一样的方法名,子类会按照按继承的顺序 执行对应的父类方法.
4.3 super() 在有些场景,我们不但要在子类中实现父类的方法,还需要执行父类的方法,那就可以使用super()
函数来调用,如场景示例: 如我们要操作一个商品数据库,在操作之前,需要先建立连接.
class Database : def __init__ (self, db_name ): print ("第一步: 和 {} 数据库建立连接" .format (db_name))class GoodsDb (Database ): def __init__ (self, db_name ): super ().__init__(db_name) print ("第二步: 操作 {} 数据库" .format (db_name)) from basis import dbif __name__ == "__main__" : it = db.GoodsDb("商品" )
5. 面向接口编程 Python
原生是不支持抽象类和接口,有时我们想做到和其他语言一样面向接口编程时,可以通过使用关键字:isinstance
:
5.1 使用语法
5.2 使用示例 class Order : def __init__ (self, accountName, totalAmount, payAmount ): self.accountName = accountName self.payAmount = payAmount self.totalAmount = totalAmount def createOrder (self ): print ("支付{}元,创建订单" .format (self.payAmount)) def deductAmount (self ): print ("扣除支付金额:{}元,余额:{}元" .format (self.payAmount, self.totalAmount - self.payAmount))class PayGoods (Order ): pass class RefundGoods : pass from basis import orderdef useIsinstance (cl ): isRes = isinstance (cl, order.Order) if not isRes: print ("参数不属于Pay类的对象" ) return cl.createOrder() cl.deductAmount()if __name__ == "__main__" : p = order.PayGoods("微信" , 100 , 20 ) print ("------传入下单类------" ) useIsinstance(p) print ("------传入退货类------" ) r = order.RefundGoods() useIsinstance(r)