Python学习---面向对象的学习[基础]

python

面向对象

面向对象的三大特性是指:封装、继承和多态。

说明: Python可以函数式编程,也可以面向对象编程

l 面向过程:根据业务逻辑从上到下写垒代码

l 函数式 :将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

l 面向对象:对函数进行分类和封装,让开发“更快更好更强...”

面向对象使用场景: 多个函数中,有相同的参数时,考虑面向对象编程【sql连接等】

需要封装一部分内容的时候,就考虑用类解决

函数和面向对象的区别:定义 + 执行的区别

类的创建以及self的含义:self代表调用该方法的执行对象

class Bar:

def foo(self, name, age, gender, content):

print(self.school, self.haha, name, age, gender, content)

z = Bar()

z.school = 'peking'

z.haha = 'hhh'

print(z.school)

z.foo('ftl', 123, 'male', 'hello world')

构造方法

构造方法__init__(self, args):  函数的初始化的时候自动执行

class Bar:

# 构造方法

def __init__(self, name, age, gender, content):

self.name = name

self.age = age

self.gender = gender

self.content = content

self.boold = 'O' # 初始化默认的参数

print('__init__') # __init__

print(name, age, gender, content, self.boold) # hhh 23 male hello world

z = Bar('hhh', 23, 'male', 'hello world') # hhh 23 male hello world O

父类调用

1. super的调用:super(子类函数名, 调用的self),  eg, super(Son, self),先认儿子,再找调用者

2. Father.__init__(self):  由父类名直接调用,我们由对象调用方法的时候,Py会自动帮我们传递self参数,但是由Father类直接调用的时候,需要把调用对象z传递过去。

class Father:

def __init__(self):

print('Father')

def hello(self):

print('Father:hello')

class Son(Father):

def __init__(self):

# super(Son, self).__init__()# 这里super(子类名,self)调用父类的init方法

Father.__init__(self) # 这里父类名.方法(self) 调用父类方法

# 父类名调用的时候,缺少参数报错 __init__() missing 1 required positional argument: 'self'

print('Son')

def hello(self):

print('Son:hello')

super(Son, self).hello() # 调用父类的方法

def world(self):

print('son:world')

z = Son()

z.hello()

z.world()

 封装性

将内容封装到某个地方,以后再去调用被封装在某处的内容。

特 性:

将内容封装到某处

从某处调用被封装的内容

class Bar:

def foo(self, content):

print(self.name, self.age, self.gender, content)

z = Bar()

z.name = 'ftl'

z.age = 12

z.gender = 'male'

z.foo('hello world') # ftl 12 male hello world

继承性:

子可以继承父的内容。将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。

1、Python的类可以继承多个类,Java和C#中则只能继承一个类

2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先

继承:先在子类自己的方法中查找,然后再去父类的方法查找

class Father:

def __init__(self):

print('Father')

def hello(self):

print('Father:hello')

class Son(Father):

# def __init__(self):

# print('Son') # 子类的构造方法没有覆盖父类,则xian执行父类的构造方法

def __init__(self): # 这里的子类覆盖掉了父类的init方法,所以打印子类自己的print

print('Son')

def world(self):

print('son:world')

z = Son() # Son

z.hello()         #Father:hello

z.world() # son:world

多继承:

        a. 左侧优先

        b. 一条道走到黑

        c. 同一个根时,根最后执行

        d. self代表调用的函数对象,遇到self调用函数的时候,确定self是谁的对象,然后一定是回到原点开始往上找方法的

class BaseRequest():

pass

class RequestHandler(BaseRequest):

def server_forver(self):

print('RequestHandler: server_forver')

self.process_request() # 回到起点开始网上找,结果:Minx : process_request

def process_request(self):

print('RequestHandler: process_request')

class Minx:

def process_request(self):

print('Minx : process_request')

class Son(Minx, RequestHandler):

pass

s = Son()

s.process_request() # Minx : process_request

s.server_forver() # RequestHandler: server_forver

多态性

Python自带多态的特性,因为Python会自动判断你传入的参数是什么类型,不用特别声明

def foo(args):

print(args)

foo("hello world") # hello world

foo(1234567) # 1234567

类的一个小程序:

  Python实例---游戏人生[类的学习]

类的成员

类的成员:

字段: 2种

方法:   3种

属性: 1种

特殊成员:

1种

普通字段属于对象,只能通过对象访问

静态字段属于类,可以通过对象,也可以通过类

class province:

country = 'China' #创建全局变量country, 她是类的对象,创建类的时候生成

# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性

def __init__(self, name):

self.name = name

print(self.name, province.country)

henan = province('henan')

print(province.country) # 可以通过类调用,也可以通过类调用

print(henan.country) # 可以通过对象调用,也可以通过类调用

# print(province.name) # 不能通过对象查找类 type object 'province' has no attribute 'name'

方法:方法保存在类中,可以通过类查找,也可以通过对象调用,但是前提是都要先创建一个类的对象

class Province:

country = 'China' # 创建全局变量country, 她是类的对象,创建类的时候生成

# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性

def __init__(self, name):

self.name = name

def fun(self):

print(self.name, Province.country)

henan = Province('henan')

henan.fun() #推荐使用

# Province.fun() #需要传递对象过去 fun() missing 1 required positional argument: 'self'

Province.fun(henan)

静态方法:@ staticmethod装饰器来完成静态方法,此时可以省略self参数,直接由类调用

class Province:

country = 'China' # 创建全局变量country, 她是类的对象,创建类的时候生成

# def __init__(self, name, country='CHINA'): # 这里的name是对象的字段,类似Java中的属性

def __init__(self, name):

self.name = name

@staticmethod

def fun(city, house): # 可以不用传递self参数

print(Province.country, city, house)

henan = Province('henan')

henan.fun('HuNan', 'Chaoyang')

Province.fun('HuNan', 'Chaoyang') # 推荐使用,直接用类调用,此时的self参数可以不用传递

类方法:由类直接调用,必须传递一个形式参数,此时python会自动帮我们传递一个类名过去,所以一般命名为cls

class Province:

@classmethod

def class_method(cls): #必须传递一个形式参数,python自动传递类名过去

# cls 是类名,不依赖对象

print('class_method:', cls) # 此时python会自动帮我们传递一个类名过去

Province.class_method() # 由类直接调用,此时python会自动帮我们传递一个类名过去

# 结果: class_method: <class '__main__.Province'>

属性(@property):定义的时候像方法,而且也有返回值, 使用的时候像字段

class Province:

@property

def fun(self):

print('hello world')

return 'ok'

obj = Province()

ok = obj.fun

print(ok) # hello world

属性表达一:(@fun.setter/@fun.deleter):仅仅是对应关系

class Province:

@property # 用于执行obj.fun 接收值

def fun(self):

print('hello world')

return 'ok'

@fun.setter # 用于obj.fun = 123 ,重新赋值

def fun(self, val):

print(val)

@fun.deleter # 仅仅是一个对应关系,不涉及真正的删除

def fun(self):

print('delete')

obj = Province()

ok = obj.fun

print(ok)

obj.fun = 'hello Python' # 查找对应的关系

del obj.fun # 不会真正的执行删除的操作,仅仅只是一个对应关系

属性表达二:(property函数):仅仅是对应关系

class Page:

def f1(self):

return 'hhh'

def f2(self, val):

print(val)

def f3(self):

print('del')

pp = property(fget=f1, fset=f2, fdel=f3, doc='Property用法二')

p = Page()

# ret = p.f1()

# print(ret)

print(p.pp) # hhh

p.pp='hello' # hello

del p.pp # del

利用属性实现分页

class Page:

def __init__(self, page):

try:

page = int(page)

except Exception as e:

page = 1

self.page = page

@property

def start(self):

page = (self.page - 1) * 10

return page

@property

def end(self):

page = self.page * 10

return page

li = []

for i in range(100):

li.append(i)

while True:

page = input("请输入页码:")

obj = Page(page)

print(li[obj.start:obj.end])

成员修饰符

公有成员 默认公有

私有成员   __小写字段名   不能直接访问,只能间接访问

继承也不能访问父类的私有字段,只能访问共有字段

class Foo:

__school = 'xupt' # 静态私有字段,外部无法直接访问

def __init__(self, name, age):

self.name = name

# self.age = age

self.__age = age # 私有变量,外部无法直接访问

def show(self):

print(self.__age, self.__school) # 从内部简介访问

@staticmethod

def stat():

print(Foo.__school)

def __private(self):

print('privatemethod')

def f(self):

self.__private()

obj = Foo('hhh', 12)

obj.show() # 12 xupt

Foo.stat() # xupt

obj.f() # privatemethod

子类不能访问父类的私有变量

class F:

def __init__(self):

self.f_name = 'Father'

# self.__fage = 54 # 父类的私有变量

class S(F):

def __init__(self, name, age):

F.__init__(self)

self.name = name

self.__age = age

def show(self):

print(self.__age, self.name)

def showFather(self):

print(self.f_name)

print(self.__fage) # 报错,父类的私有变量

obj = S('hhh', 23)

obj.show() # 23 hhh

obj.showFather() # Father

特殊成员

    __init__     类()自动执行

    __del__ 析构方法,对象被销毁时自动触发,Py自动执行

    __call__     对象()  类()() 自动执行

    __int__      int(对象)

    __str__      str()    

    __add__

    __dict__     # 讲对象中封装的所有内容通过字典的形式返回

    __getitem__  # 切片(slice类型)或者索引

    __setitem__

    __delitem__    

    __iter__

                # 如果类中有 __iter__ 方法,对象=》可迭代对象

                # 对象.__iter__() 的返回值: 迭代器

                # for 循环,迭代器,next

                # for 循环,可迭代对象,对象.__iter__(),迭代器,next

                # 1、执行li对象的类F类中的 __iter__方法,并获取其返回值

                # 2、循环上一步中返回的对象

__call__     对象()  类()() 自动执行

class F:

def __init__(self, name, age):

self.name = name

self.age = age

print(self.name, self.age)

def __call__(self, *args, **kwargs):

print('Call')

obj = F('hhh', 23)

obj() # 等价于 F('hhh', 23)() 对象也可以添加()来执行

__int__/__str__/__add__

class F:

def __init__(self, name):

self.name = name

def __int__(self):

return 1234

def __str__(self):

return 'Father'

def __add__(self, other): # 对象的重组

# self= f('hello')

# other = ff('world')

return self.name + other.name

f = F('hello')

ff = F('world')

# print(f+ff) # 没有add方法,报错, unsupported operand type(s) for +: 'F' and 'F'

print(f+ff) # helloworld, 2个对象相加时候,会执行第一个对象的__add方法,并且将第二个对象作为参数传递过去

print(int(f)) # 1234, 对象转换为int型

print(str(f)) # Father, 对象转换为str型

__dict__     # 将对象/类中封装的所有内容通过字典的形式返回

class F:

# hello我让ld

def __init__(self, name):

self.name = name

def show(self):

print(self.__dict__)

f = F('hello')

f.show() # 打印对象里面的所有成员

print(F.__dict__) # 打印类里面的所有成员

__getitem__/__setitem__/__delitem__的使用

# 问: li本身也是一个对象,为什么可以直接用下标来取值呢?

# 答; 因为list里面有__getitem__, __setitem__, __delitem__

li = ['hello', 'world', '2017']

print(li[1])

# print(li[1:4:2])

li[1] = 'ftl'

del li[1]

# 函数利用使用__ getitem__

lass F:

def __init__(self, name):

self.name = name

def __getitem__(self, item):

if type(item) == 'slice':

print('这里采用切片调用',item.start, item.stop, item.step)

else:

print('这里采用索引调用')

return item

def __setitem__(self, key, value):

print(key, value)

def __delitem__(self, key):

print(key)

obj = F('hello')

print(obj['hello'])

obj['hello']='world'

del obj['hello']

__iter__: 迭代器的原理

class F:

def __init__(self, name, age):

self.name = name

self.age = age

def __iter__(self): # 代表F是一个可迭代对象

return iter([1, 2, 3, 4, 5]) # 返回一个迭代器

f = F('hhh', 23)

for i in f: # for循环循环next()迭代打印

print(i)


【学习参考】http://www.cnblogs.com/wupeiqi/p/4493506.html

以上是 Python学习---面向对象的学习[基础] 的全部内容, 来源链接: utcz.com/z/389123.html

回到顶部