面向对象的概念
面向过程和面向对象是两种编程方式,这两个种方式是程序员用来代码来抽象世界的不同的方式,本身无优劣之分,针对于不同的抽象,各有利弊。面向对象更倾向于用各种模板来抽象世界,每个实例就是这种抽象的具体描述,这样可以描述更加复杂的关系,且可以让行为和属性和具体的对象进行绑定。而面向过程更倾向于描述解决问题的一种流程,更加的直观,简洁高效。
一个简单的栗子:
class Dog(object): def __init__(self, name, bleed, age): self.name = name self.bleed = bleed self.age = age def speak(self): print("wang!wang!wang!") def show(self): print('我叫 %s 我是一只 %s 狗,我今年 %s 岁了' % (self.name, self.bleed, self.age)) d = Dog("mjj", "京巴", 3) d.speak() d.show()
具体定义描述
class Dog(object):
首先class 是一个关键字,标志了需要定义一个类;
Dog 是这个定义的类的名字,后面我们通过这个类的名字进行数据的实例化调用
(object)是表示此类继承了object类,括号中是父类的名字,python支持多继承,所以在括号内可以写多个类名,但是需要用逗号进行分割!
*object是所有python定义类的父类,默认继承,若没有具体的类要继承 那么无需写object,因为可以省略。
类中的方法:
def speak(self): print("wang!wang!wang!")
方法定义没有任何特殊,但是和一般的方法定义,有一个默认的参数,self,这个self标志是实例自己。方法中可以使用self来调用自己的一些实例属性值,类属性的值,可以使用类名.类属性名来进行访问
d = Dog("mjj", "京巴", 3)
创建一个名字叫d实例,它是Dog的一个具体的对象。初始化默认就会调用类的__init__(self,xxxx)方法,因为这个方法是实例方法,所以,self默认,只需要进行self后的形参列表进行传值即可。
d.speak()
使用实例名称.方法名称调用方法,执行你所需的逻辑。
概念解析
类:class关键字后面定义的代码,可以看作一个类的定义。有时候我们说的类,其实就是这样的类的定义。
类名:可以看作一个模板,在创建实例的时候进行调用
实例名: 通过调用类名()创建的一个类的实例
类方法:一般会有一个@classmethod标签 通过 类名.方法名/实例名称.方法名 进行调用,不可以访类变量,但是不能访问实例变量
实例方法:只能通过 实例变量.方法 名称进行调用,可以访类变量,可以访问实例变量
静态方法:一般会有一个@staticmethod标签
对象之间的关系
组合关系:某些东西只有在一起的时候才能正常工作,下面这个weapon和person就是一个组合关系
class Dog():
__force_dict = {'京巴': 30, '藏獒': 80}
def __init__(self, name, bleed, age):
self.name = name
self.bleed = bleed
self.age = age
self.life_val = 100
self.force_val = Dog.__force_dict.get(bleed)
@classmethod
def speek(self):
print("wang!wang!wang!")
def bite(self, p):
p.life_val -= self.force_val
print("%s 张口咬了 %s , %s 掉血 %s 还剩 %s 血量" % (self.name, p.name, p.name, self.force_val, p.life_val))
class Weapon():
def knift(self, d):
d.life_val -= 80
print("拿刀捅了 %s , %s 掉血 %s 还剩 %s 血量" % (d.name, d.name, 80, d.life_val))
def gun(self, d):
d.life_val -= 100
print("拿枪扫射了 %s , %s 掉血 %s 还剩 %s 血量" % (d.name, d.name, 100, d.life_val))
def stick(self, d):
d.life_val -= 50
print("拿打狗棍打了 %s , %s 掉血 %s 还剩 %s 血量" % (d.name, d.name, 50, d.life_val))
class Person():
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
self.life_val = 100
self.weapon = Weapon()
d = Dog('mjj', '京巴', 3)
p = Person('ty', 'male', 30)
d.bite(p)
p.weapon.knift(d)
两个对象之间存在组合的关系,一方是另外一方的某个实例属性,这样的关系,叫做组合关系。
依赖关系
class Dog(): def __init__(self, name, bleed, age, person): self.name = name self.bleed = bleed self.age = age self.person = person def say_hi(self): print("我是%s,我的主人是%s" % (self.name, self.person.name)) class Person(): def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age p = Person('tang', 'male', 30) d = Dog('mjj', '京巴', 3, p) d.say_hi()
关联关系
class Relationship(): def __init__(self): self.couple = [] def make_couple(self, obj, obj2): self.couple = [obj, obj2] def break_up(self): self.couple = [] def get_parter(self, obj): if len(self.couple) > 0: for temp in self.couple: if obj != temp: return temp return None class Person(): def __init__(self, name, sex, age, relation): self.name = name self.sex = sex self.age = age self.life_val = 100 self.relation = relation relationship = Relationship() p1 = Person('mjj', 'male', 24, relationship) p2 = Person('zqq', 'famale', 23, relationship) relationship.make_couple(p1, p2) print(p1.relation.get_parter(p1).name) print(p2.relation.get_parter(p2).name)
聚合关系:
继承关系
狗继承自动物,所以有动物的所有特性,动物的方法也可以被狗使用
class Animal(): def __init__(self, name, age): self.name = name self.age = age def eat(self): print("动物吃东西狼吞虎咽!") class Dog(Animal): def __init__(self, name, age, bleef): super().__init__(name, age) self.bleef = bleef def show(self): print("狗在表演站立") d = Dog('mjj', 3, '京巴') d.eat() d.show()
类的三大特性
继承:参看上面
封装:将一些不希望被在类外调用的方法或者属性进行隐藏,这样的方式叫做封装
封装方法:在方法名字前加 __(两个下划线)
封装属性:在属性前面加__(两个下划线)
这样在调用的时候会出现如下错误:AttributeError: 'Dog' object has no attribute 'xxx'
强制调用封装函数:对象._类名+方法名()
d._Dog__show()
多态性
子类重写了父类的方法,那么通过子类调用此方法,那就会先找子类的方法列表中是否存在,不存在,会按照继承顺序,依次向上查找父类,找到就调用。
class Animal(): def __init__(self, name, age): self.name = name self.age = age def eat(self): print("动物吃东西狼吞虎咽!") class Dog(Animal): def __init__(self, name, age, bleef): super().__init__(name, age) self.bleef = bleef def __show(self): print("狗在表演站立") def eat(self): print("狗吃东西吧唧嘴!") d = Dog('mjj', 3, '京巴') d.eat() d._Dog__show()
这个eat方法就是体现了多态性!
方法的标签
@property
class Flight: def __init__(self, airline): self.airline = airline self.__flight_sta = None @property def flight_status(self): print("通过机场的航班查询飞机的状态。。。") if self.__flight_sta == 0: print("飞机还未到达机场") elif self.__flight_sta == 1: print("飞机正在登机") elif self.__flight_sta == 2: print("飞机已经离开机场") @flight_status.setter def flight_status(self, value): self.__flight_sta = value f = Flight("M219") # f.flight_status f.flight_status = 1 f.flight_status
可以将方法看作一个属性来范文,设置属性也可以当作一个属性来赋值
热加载
__import__("XXXX")
或者(官方推荐使用类库的方式进行加载)
import importlib
importlib.import_module("XXXX")
双下划线方法
# 两个对象是否相等 isinstance()方法可能会用到
def __eq__(self, other): pass
# 获取实例属性的长度会调用此方法 def __len__(self): pass #计算hash的结果值会调用此方法 def __hash__(self): pass #获取某个属性会调用此方法 def __getitem__(self, item): pass #设置属性值会调用此方法 def __setitem__(self, key, value): pass #删除属性值会调用此方法 def __delitem__(self, key): pass
def __init__(self):
pass
#类似STR函数 但是场景有不一样
def __repr__(self):
pass
#直接使用print(obj)则调用此函数
def __str__(self):
pass
#删除对象时候调用
def __del__(self):
pass
析构函数
创建和销毁对象会用到的函数 称之为析构函数
def __init__(self): pass def __repr__(self): pass
反射
反射主要是通过这
hasattr(),getattr(),setattr(),delattr()来进行设置
if hasattr(d, 'name'): obj = getattr(d, 'name') print(obj) if hasattr(d, 'show'): obj = getattr(d, 'show') if callable(obj): print('是函数') obj() def print_char(char, num): val = char * num print(val) setattr(d, "print_char", print_char) d.print_char("*", 10)
单例模式和__new__()
class Printer(): instance = None def __init__(self, file): if hasattr(self, "files"): self.files.append(file) else: self.files = [] self.files.append(file) def print(self): for temp in self.files: print(temp) def __new__(cls, *args, **kwargs): if cls.instance == None: cls.instance = super().__new__(cls) return cls.instance p1 = Printer("pdf") p2 = Printer("word") p3 = Printer("excel") print(p1, p2, p3) p3.print()
标签:__,name,python,self,面向对象,print,age,def From: https://www.cnblogs.com/jones-walker/p/18036147