Python 进阶_OOP 面向对象编程_类属性和方法

简介: 目录目录类属性调用类属性查看类属性特殊的类属性类方法真构造器 __new__类属性在理解类属性之前要先搞清楚 实例属性 和 函数属性 之间的区别: 1. 实例属性:指的是实例化类对象的属性,需要在类中使用 self 关键字来将其和实例化对象绑定的属性。

目录

类属性

在理解类属性之前要先搞清楚 实例属性函数属性 之间的区别:
1. 实例属性:指的是实例化类对象的属性,需要在类中使用 self 关键字来将其和实例化对象绑定的属性。
2. 函数属性:指的是定义在函数体内的属性,其可以是实例属性,也可以是类属性。
3. 类属性:是一个与实例无关的属性,比起实例属性而言,它更加的 静态,当定义在类方法中时,并不会因为方法调用的完毕而被回收。类属性,在类定义中直接指定,无须 self 关键字,所以也只能在类中使用。所以类属性只能通过类的成员方法或类调用来更新。

静态:表示一个对所有实例而言都是相对固定的值

NOTE:类属型也称之为 静态属性,当我们定义一个类静态属性时,无须实例化对象,直接可以通过类来调用该属性,直到这个类被回收为止。如果在 Java 中,你需要使用 static 来指定。当然类的实例化对象也可以通过句点标识符来调用和更改,但此时的更改并不会影响原来的类静态属性。

EXAMPLE:

In [48]: class AClass(object):
    ...:     LOG = 'Define a class'
    ...:

In [49]: AClass.LOG
Out[49]: 'Define a class'

In [50]: a_object = AClass()

In [51]: a_object.LOG
Out[51]: 'Define a class'

In [52]: a_object.LOG = 'Call the static attribute.'

In [53]: a_object.LOG
Out[53]: 'Call the static attribute.'

In [54]: AClass.LOG
Out[54]: 'Define a class'

通过这个例子可以看出类属性的调用可以完全无需实例化一个类对象。

调用类属性

注意:在类定义的函数体中调用类属性,需要通过 类名结合句点标识符 的方式来调用,否则会出发 NameError

In [93]: class AClass(object):
    ...:     LOG = 'Define a class'
    ...:     def my_func(self):
    ...:         print ''.join(['log: ', AClass.LOG])
  # 函数体中
    ...:     print ''.join(['log is: ', LOG])
  # 类体中
    ...:
    ...:
log is: Define a class

In [91]: a_object = AClass()

In [92]: a_object.my_func()
log: Define a class

查看类属性

Python 为此提供了两个方法:

  • 通过 dir() 来查看类属性
In [55]: dir(AClass)
Out[55]:
['LOG',
 '__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']
  • class.__dict__ 来查看类属性,等效于vars(AClass)
In [83]: AClass.__dict__
Out[83]:
dict_proxy({'LOG': 'Define a class',
            '__dict__': <attribute '__dict__' of 'AClass' objects>,
            '__doc__': None,
            '__module__': '__main__',
            '__weakref__': <attribute '__weakref__' of 'AClass' objects>})

两者的区别在于:前者仅能查看类属性的列表,后者可以查看类属性的键值对字典。

特殊的类属性

从上述的例子可以看出类中处理我们定义的 LOG 属性之外还有很多以双下划线 “__” 开头和结尾的属性,这些属性都是 Python 的特殊属性。

特殊属性 作用
C.name 类的名字(String)
C.doc 类的文档(String)
C.bases 子类的父类元组(Tuple)
C.dict 类的属性字典(Dict)
C.module 类所有的模块名称
instance.class 类实例对象的类名称

NOTE:其中 __dict__ 是一个包含了类属性的字典,方 Python 解析器访问一个类属性时,就会在这个字典中搜索。如果在该类的字典中没有搜索到,那么就会到该类的父类的属性字典中搜索。这样的话就能够将不同类之间的属性名隔离开来,在子类中对属性字典的修改并不会影响到父类的属性字典。

类方法

类方法就最基本的特征就是需要传递一个 class 对象作为方式的实参。

真·构造器 __new__()

__init__() 相比 __new__() 才是真正的构造器,实际上,在 Python 解析器中是先调用了 __new__() 生成一个实例,再将该实例对象传入 __init__() 实现初始化操作。但 __new__() 很少需要我们去重载,一般只有在派生了不可变类型的子类后需要重载,EG. 派生 String/Int/Tuple 等

为什么说 __new__() 是真·构造器呢?
因为这个特殊的类方法是真的返回了一个类的实例对象,而不像 __init__() 是传入了一个实例化对象。

EXAMPLE:不可表类型的派生

class RoundFloat(float):
    def __new__(cls, val):
        return float.__new__(cls, round(val, 2)) #因为 __new__ 是一个类方法,所以我们要显式的传递一个类对象

类 RoundFloat 是类 float 的子类,我们通过重载父类的 __new__() 构造器来定制一个新的不可变类型(Python 2.2之后将类和类型统一了,所以可以继承 Python 的内置数据类型)。当实例化 RoundFloat 的对象时,实际上是实例化了Python 内置数据类型 Float 的对象,并对这个对象做了一些定制化的操作(round(val, 2))。
NOTE:即便我们也可以通过重载 __init__() 来实现这个结果,但这里却不能这么做。因为如果 __new__() 没有被重载的话,仍会默认调用父类 Float 的构造器,创建 Float 类型的对象,而不是创建现在的 RoundFloat 类型对象。这也是两者的本质区别。

相关文章
|
6天前
|
Python
python魔法方法如何应用
这个Python示例展示了类继承和方法重写。`Student`类继承自`Person`,并覆盖了`say_hello`方法。通过`super().__init__(name)`调用父类的`__init__`初始化`name`属性,`Student`添加了`age`属性,并在重写的`say_hello`中使用。创建`Student`实例`student`并调用其`say_hello`,输出定制的问候信息。
16 1
|
1天前
|
Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
13 0
|
1天前
|
索引 Python
python 格式化、set类型和class类基础知识练习(上)
python 格式化、set类型和class类基础知识练习
15 0
|
3天前
|
Python
python学习12-类对象和实例对象
python学习12-类对象和实例对象
|
7天前
|
机器学习/深度学习 人工智能 算法
|
7天前
|
安全 Python
python字典的内置方法
Python字典主要方法包括:`keys()`(返回所有键)、`values()`(返回所有值)、`items()`(返回所有键值对)、`get()`(安全取值,键不存在时返回默认值)、`setdefault()`(设置默认值)、`update()`(合并字典)、`pop()`(删除并返回值)、`clear()`(清空字典)、`copy()`(浅拷贝)、`fromkeys()`(新建字典并设置默认值)、`popitem()`(随机删除键值对)。
7 0
|
10天前
|
Python
Python面向对象编程学习应用案例详解
面向对象编程在Python中通过类定义对象结构和行为。示例:1) 使用`class`关键字定义类,如`class Person`;2) `__init__`方法初始化对象属性,如`self.name`和`self.age`;3) 实例化对象,如`person1 = Person(&quot;张三&quot;, 25)`;4) 访问属性和方法,如`person1.name`;5) 定义类方法,如`def introduce(self)`;6) 调用方法,如`person1.introduce()`;7) 类继承,如`class Student(Person)`;8) 多态,通过继承重写方法实现。
9 1
|
开发者 Python
继承的注意事项类属性案例练习 | 手把手教你入门Python之六十四
在Python中,继承可以分为单继承、多继承和多层继承。
继承的注意事项类属性案例练习 | 手把手教你入门Python之六十四
|
开发者 Python 设计模式
|
7天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。

热门文章

最新文章