Python进阶-面向对象

类的成员

类的成员可以分为三类:字段、方法、属性

一:字段:

普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同

  • 普通字段属于对象
  • 静态字段属于类

字段的定义和使用

class Province:
    # 静态字段
    country = ‘中国‘
    def __init__(self,name):
        # 普通字段
        self.name = name
# 直接访问普通字段
obj = Province(‘北京‘)
print obj.name

# 直接访问静态字段
print Province.country

点睛:

1:谁来调用:

从上面可以看出普通字段需要通过对象来访问,静态字段通过类来调用。

2:存储的位置

  1. 静态字段只存在把内存中一份,存在类的内存中
  2. 普通字段在每个对象中都要创建一份。

通过类创建对象的时候,如果每个对象都具有相同的字段,那么就使用静态字段

二:方法

普通方法、静态方法、类方法。三种方法在内存中都属于类,区别在于调用方式不同

  • 普通方法:由对象调用,至少一个self参数,执行普通方法时,自动将调用该方法的对象赋值给self
  • 类方法:由类调用,至少一个cls参数,执行类方法时,自动将调用该方法的类赋值给cls
  • 静态方法:由类调用,无默认参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

class Foo:

    # 初始化类

    def __init__(self):

        pass

    # 定义普通方法,至少有一个self参数

    def p(self):

        print ‘普通方法‘

    # 定义类方法,至少有一个cls参数

    @classmethod

    def q(cls):

        print ‘类方法‘

    # 定义静态方法

    @staticmethod

    def w():

        print ‘静态方法‘

# 调用普通方法

a = Foo()

ret = a.p()

# print ret

# 调用类方法

Foo.q()

# 调用静态方法

Foo.w()

点睛:

相同点:对于所有的方法而言,均属于类中,所以在内存中也之保存一份

不同点:方法调用者不同,调用方法时,自动传入的参数不同

三:属性

1:属性的基本使用


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

class Foo:

    def func(self):

        # print ‘func‘

        return ‘方法调用的返回值‘

    # 定义属性

    @property

    def prop(self):

        # print ‘prop‘

        return ‘属性调用的返回值‘

# 调用方法

obj = Foo()

ret = obj.func()

print ret

# 调用属性

ret1 = obj.prop

print ret1

点睛:

  1. 定义时,在普通方法的基础上在上面添加@property装饰器
  2. 属性仅有一个self参数
  3. 调用时,无需括号

方法:

obj = Foo()

ret = obj.func()

属性:

obj = Foo()

ret = obj.prop

属性存在的意义:访问属性时,可以制造出和访问字段完全相同的假象

实例:

对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第M条到第N条的所有数据,这个分页功能包括:

  1. 根据用户请求的当前和总数据条数计算出m和n
  2. 根据m和n去数据库请求数据

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Pager:

    def __init__(self,current_page):

        # 用户当前请求的页面

        self.current_page = current_page

        # 每页默认显示10条

        self.per_items = 10

    # 定义属性

    @property

    def start(self):

        val = (self.current_page - 1) * self.per_items

        return val

    @property

    def end(self):

        val = self.current_page * self.per_items

        return val

# 调用属性

p = Pager(2)

print  p.start

print  p.end

# 结果:

# 10

# 20

2:属性的两种定义方式

装饰器、静态字段

装饰器:在方法上应用装饰器

静态字段:在类中定义值为property对象的静态字段

装饰器方式:

经典类,具有一种@property装饰器

# 定义类
class Foo:
    @property
    def fun(self):
        return ‘caoxiaojian‘
# 调用属性
obj = Foo()
ret = obj.fun
print ret
# 自动执行 @property修饰的fun方法,并获取方法的返回值

新式类,具有三种@property装饰器


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Goods(object):

    @property

    def price(self):

        print ‘@property‘

    @price.setter

    def price(self,value):

        print ‘@price.setter‘,value

    @price.deleter

    def price(self):

        print ‘@price.deleter‘

# 调用

obj = Goods()

obj.price               # 自动执行@property修饰的price方法,并获取方法的返回值

obj.price = 123         # 自动执行@price.setter修饰的price方法,并将123赋值给方法的参数

del obj.price           # 自动执行@price.deleter修饰的price方法

执行结果:

@property

@price.setter 123

@price.deleter

注释:

经典类中的属性只用一种访问方式,其对应被@property修饰的方法

新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

因为新式类有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为同一个属性:获取、修改、删除

实例讲解:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class Goods(object):

    def __init__(self):

        # 原价

        self.original_price = 100

        # 折扣

        self.discount = 0.8

    @property

    def price(self):

        # 实际价格 = 原价 * 折扣

        new_price = self.original_price * self.discount

        return new_price

    @price.setter

    def price(self,value):

        # 设置原始价格

        self.original_price = value

    @price.deleter

    def price(self,value):

        # 删除原始价格

        del self.original_price

# 调用

obj = Goods()

# 获取商品价格

obj.price

# 设置原始价格

obj.price = 3000

# 删除原始价格

del obj.price

静态字段方式:

创建值为property对象的静态字段

当使用静态字段的方式创建属性时,经典类和新式类无区别


1

2

3

4

5

6

7

8

9

class Foo:

    def get_bar(self):

        return ‘caoxiaojian‘

    BAR = property(get_bar)

obj = Foo()

# 自动调用get_bar方法,并获取方法的返回值。

ret = obj.BAR

print ret

property的构造方法中有个四个参数

  • 第一个参数是方法名,调用对象.属性时自动触发执行方法
  • 第二个参数是方法名,调用对象.属性 = xxx时自动触发执行方法
  • 第三个参数是方法名,调用del 对象.属性时自动触发执行方法
  • 第四个参数是字符串,调用对象.属性.__doc__此参数是该属性的描述信息

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

class Foo:

    def get_bar(self):

        return ‘caoxiaojian‘

    # 必须有两个参数

    def set_bar(self):

        return ‘set value‘ + value

    def del_bar(self):

        return ‘caoxiaojian===2‘

    BAR = property(get_bar, set_bar, del_bar,‘description......‘)

obj = Foo()

print obj.BAR           # 自动调用第一个参数中定义的方法:get_bar

obj.BAR = "caogaotian"  # 自动调用第二个参数中定义的方法:set_bar方法,将"caogaotian" 当作参数传入

print obj.BAR

del  obj.BAR            # 自动调用第三个参数中定义的方法:del_bar

print obj.del_bar()    

obj.BAR.__doc__         # 自动调用第三个参数中设置的值:‘description......‘

‘‘‘

结果输出:

caoxiaojian

caogaotian

caoxiaojian===2

‘‘‘

类成员的修饰符

两种形式:

  1. 私有成员:只有在类的内部才能访问的方法
  2. 公有成员:在任何地方都能访问

定义的不同:

私有成员命名时,前面两个字符是下划线。(特殊成员除外,例如:__init__等)

class C:
    def __init__(self):
        self.name = ‘公有字段‘
        self.__name = ‘私有字段‘

私有成员和公有成员的访问限制不同

静态字段

  • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
  • 私有静态字段:仅类内部可以访问

公有静态字段


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class C:

    name = ‘公有静态字段‘

    def func(self):

        print C.name

class D(C):

    def func_1(self):

        print C.name

# 直接使用类访问

C.name

# 类内部访问

obj = C()

obj.func()

# 派生类内部访问

obj_1 = D()

obj_1.func_1()

‘‘‘

结果打印:

公有字段

公有字段

‘‘‘

私有静态字段


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

class C:

    __name = ‘公有静态字段‘

    def func(self):

        print C.__name

class D(C):

    def func_1(self):

        print C.__name

# 类中访问

# C.__name    # 错误

# 类内部访问

obj = C()

obj.func()

# 派生类中访问

# obj_1 = D()    # 错误

# obj_1.func_1()

普通字段

  • 公有普通字段:对象、类、派生类都可以访问
  • 私有普通字段:只能在类内部访问

公有普通字段


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

class C:

    def __init__(self):

        self.foo = ‘公有字段‘

    def func(self):

        # 在类内部调用访问

        print self.foo

class D(C):

    def show(self):

        # 在派生类中调用访问

        print self.foo

obj = C()

# 通过对象访问

print type(obj.foo)

print  obj.foo

print ‘===========‘

# 类的内部访问

obj.func()

print ‘===========‘

obj_1 = D()

# 在派生类中访问

obj_1.show()

‘‘‘

结果打印:

<type ‘str‘>

公有字段

===========

公有字段

===========

公有字段

‘‘‘

私有普通字段


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

class C:

    def __init__(self):

        self.__foo = ‘私有普通字段‘

    def func(self):

        # 类的内部调用访问

        print self.__foo

class D(C):

    def show(self):

        # 在派生类中调用访问

        print self.__foo

obj = C()

# obj.__foo      # 通过对象访问:报错

obj.func()       # 通过类内部访问

obj_1 = D()

#obj_1.show()    # 通过派生类调用访问: 报错

类的特殊成员

1:__doc__

表示类的描述信息

class C:
    """
    这是描述信息,你看什么看??
    """
    def func(self):
        pass
print C.__doc__
# 输出:这是描述信息,你看什么看??

2:__module__和__class__

__module__:表示当前操作的对象在哪个模块

__class__: 表示当前操作的对象的类是哪一个

在tmp模块下面有test.py和test1.py

test.py

class C:
    def __init__(self):
        self.name = ‘caoxiaojian‘

test1.py

from test import C
# 根据导入的C类创建对象
obj = C()
# 获取对象中的模块名
print obj.__module__   # test
# 获取对象中的类名
print obj.__class__    # test.C

3:__init__

构造方法,通过类创建对象时,自动触发执行

class C:
    def __init__(self,name):
        self.name = name
        self.age = 18
obj = C(‘caoxiaojian‘) # 自动执行类中的__init__方法
print obj.name

4:__call__

对象后面加括号,触发执行

点睛:

构造方法的执行是由创建对象触发的。即:对象名 = 类名()

__call__方法的执行由对象后面加括号触发的。即:对象()或者类名()()

class C:
    def __init__(self):
        pass
    def __call__(self, *args, **kwargs):
        print ‘__call__‘

obj = C()      # 触发__init__
obj()          # 触发__call__

5:__dict__

类或对象中的所有成员

点睛:

类的普通字段属于对象,类中的静态字段和方法等属于类


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class Province:

    country = ‘china‘

    def __init__(self,name,count):

        self.name = name

        self.count = count

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

        print ‘func===func‘

# 获取类中的成员:静态字段和方法

print Province.__dict__

# {‘country‘: ‘china‘, ‘__module__‘: ‘__main__‘, ‘func‘: <function func at 0x021DA7F0>, ‘__init__‘: <function __init__ at 0x021DA870>, ‘__doc__‘: None}

# 调用类创建obj对象

obj = Province(‘shandong‘,100000)

print obj.__dict__

# {‘count‘: 100000, ‘name‘: ‘shandong‘}

# 调用类创建foo对象

foo = Province(‘beijing‘,20000)

print foo.__dict__

# {‘count‘: 20000, ‘name‘: ‘beijing‘}

类的分类:

经典类和新式类

# 经典类
class func:
    def Foo(self):
        pass
# 新式类
class func_new(object):
    def Foo_new(self):
        pass

点睛:

区别:就是在类的后面加个object

类的继承


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

# 新式类

class D(object):

# 经典类

#class D:

    def bar(self):

        print ‘D.bar‘

class C(D):

    def bar(self):

        print ‘C.bar‘

class B(D):

    pass

class A(B,C):

    pass

a = A()

a.bar()

‘‘‘

经典类:深度优先  D.bar

新式类:广度优先  C.bar

‘‘‘

点睛:

经典类:深度优化

新式类:广度优化

时间: 2024-10-11 17:31:29

Python进阶-面向对象的相关文章

Python进阶---面向对象的程序设计思想(一)

thon的面向对象 一.面向过程与面向对象的对比 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了程序的复杂度 缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身. 应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等. 面向对象的程序设计的核

Python进阶---面向对象第三弹(进阶篇)

Python对象中一些方法 一.__str__ class Teacher: def __init__(self,name,age): self.name=name self.age=age self.courses=[] def teach(self): print('%s teach' %self.name) def __str__(self): return '<name:%s age:%s>' %(self.name,self.age) class Course: def __init

Python进阶 函数式编程和面向对象编程等

函数式编程 函数:function 函数式:functional,一种编程范式.函数式编程是一种抽象计算机的编程模式. 函数!= 函数式(如计算!=计算机) 如下是不同语言的抽象 层次不同 高阶函数:能接收函数做参数的函数 变量可以指向函数 函数的参数可以接收变量 一个函数可以接收另一个函数作为参数 例子: 接收abs函数, 定义一个函数,接收x,y,z三个参数.其中x,y是数值,z是函数 . 1 2 3 def add(x,y,z):     return z(x)+z(y) print ad

what&#39; the python之面向对象(进阶)

面向对象的知识点补充(进阶版) classmethod和staticmethod:这两个函数的用途就是可以不用实例化对象就可以调用方法 class Classmethod_Demo(): role = 'dog' @classmethod def func(cls): print(cls.role) Classmethod_Demo.func() class Staticmethod_Demo(): role = 'dog' @staticmethod def func(): print("当普

Python之面向对象进阶

Python之面向对象进阶 进阶有:Python 类的成员.成员修饰符.类的特殊成员. 一.类的成员 类的成员可以分为三大类:字段.方法和属性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份. 1.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 1 class Province:

Python中面向对象初识到进阶

面向对象初识到进阶 # 面向对象结构: # class 类名: # def __init__(self,参数1,参数2): # self.对象的属性1 = 参数1 # self.对象的属性2 = 参数2 # # def 方法名(self):pass # # def 方法名2(self):pass # # 对象名 = 类名(1,2) #对象就是实例,代表一个具体的东西 # #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法 # #括号里传参数,参数不需要传self,其他与

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装: ? ? ? ? ? ?将一些东西封装到一个地方,你还可以取出来 ? ? ? ? ? ?类设置静态属性, 设置一些方法 或者 对象, 对象可以在其对象封装一些属性 多态: ? ? ? ? ? ?python默认支持多态, 多态指的是一种事务具有多种形态 ? ? ? ? ? ?1.多态可以增加代码的灵活度: ? ? ? ? ? ?2.以继承和重写父类方法为前提: ?

有哪些比较好的讲Python进阶的博客?

Python是一种动态解释型的编程语言,它可以在Windows.UNIX.MAC等多种操作系统以及Java..NET开发平台上使用.不过包含的内容很多,加上各种标准库.拓展库,乱花渐欲迷人眼.因此如何进阶Python显得非常重要. 接下来看看比较好的讲Python进阶的博客,我这有十个,希望对你有帮助. 第一个是Planet Python,这是最出名的python博客其中之一: 第二个博客是Eli Bendersky 的博客:Eli Bendersky's website: 第三个博客是Code

一、Python 进阶 之 函数式编程

Python 进阶 之 函数式编程 写在前面 入门阶段的系列笔记传送门 → 进这里 已经掌握了基础的内容如下: 变量和数据类型:Python 内置的基本类型 List 和 Tuple:顺序的集合类型 条件判断和循环:控制程序流程 Dict 和 Set:根据Key访问的集合类型 函数:定义和调用函数 切片:如何对 list 进行切片 迭代:如何用 for 循环迭代集合类型 列表生成式:如何快速生成列表 接下来我要学会: 函数式编程 如何使用 Python 的模块(内置模块和第三方模块) 面向对象编