猪行天下之Python基础——8.1 类与对象(中)

简介: 内容简述: 1、面相对象的理解 2、类与对象 3、继承 4、组合 5、对象相关的内置函数

⑤ 类函数,成员函数与静态函数


「类函数」用于访问类属性,使用@classmethod装饰器来修饰,第一个参数是cls,类本身用于调用类属性但是不能访问实例属性。类方法可以通过类直接调用,或通过实例直接调用。但无论哪种调用方式,最左侧传入的参数一定是类本身!!!代码示例如下:


class A:
    @classmethod
    def fun_a(cls):
        print(type(cls), cls)
if __name__ == '__main__':
    A.fun_a()
    a = A()
    a.fun_a()


运行结果如下


<class 'type'> <class '__main__.A'>
<class 'type'> <class '__main__.A'>


「成员函数和类实例绑定」类实例化后才能调用,它的第一个参数表示实例本身,一般用self表示成员函数可以直接操作对象内部的数据。如果使用类直接调用成员函数需要显式地将实例作为参数传入。代码示例如下:


class B:
    def fun_b(self):
        print("Call fun_b()")
if __name__ == '__main__':
    b = B()
    b.fun_b()
    B.fun_b(b)  # 类调用成员函数需将实例传入


运行结果如下


Call fun_b()
Call fun_b()


静态函数」,在定义上面的fun_b函数的时候,智能提示里就有一个Make method  static的选项,对于这种不需要self参数的函数(无需实例参与)都可以定义成静态函数调用过程中无需将类实例化。使用@staticmethod装饰器声明,通过 类名.函数名实例.函数名进行调用,代码示例如下:


class C:
    @staticmethod
    def fun_c():
        print("Call fun_c()")
if __name__ == '__main__':
    C.fun_c()
    c = C()
    c.fun_c()


运行结果如下


Call fun_c()
Call fun_c()


⑥ 访问控制


所谓的访问控制,就是「类的属性和方法是公有还是私有」,如果属性和方法只能在类内部访问,而不能被实例访问的话,我们就称这个属性或方法为私有的

 

Python和其他编程语言不同,没有类似于public和private这样的访问权限修饰符,而是采用一种「名字改编技术」。默认公有,而私有的属性名和方法名会加上两下划线,比如下面的__skill,当然这只是伪私有,改成了_类名私有属性/方法名,比如下面调用people._Person__skill,是可以访问到私有成员的:


class People:
    sex = 1  # 类属性
    __skill = "敲代码"  # 私有类属性,只能类内部访问,外部无法访问
    def speak(self):
        print("我是一个人,技能是:%s" % self.__skill, end='\t')
people = People()
people.speak()
people.sex = -1
print("性别:" + ("男" if people.sex == 1 else "女"))
print("访问私有属性:%s" % people._People__skill)


运行结果如下


我是一个人,技能是:敲代码   性别:女
访问私有属性:敲代码


虽然可以这样访问到私有成员,但是不建议这样做!


另外还有一种「单下划线开头的变量名或方法名」,同样是私有成员,不过类和实例都能访问,也会被子类继承。如果你不想属性或方法被子类继承就还是用双下划线吧!还有一种「开头结尾都是双下划线的属性或函数」是类的特殊成员,有特殊用途,比如上面的__init__初始化方法;最后如果你「定义的变量和某个保留关键字冲突」的话,可以使用单下划线作为后缀,比如:in_ = 1。


⑦ 动态绑定


Python中可以「动态地为类或对象绑定属性或函数」。类动态绑定属性与函数,对该类的所有实例有效。代码示例如下:


class A:
    def __init__(self, id_):
        self.id_ = id_
# 定义一个用于动态绑定的函数
def set_name(self, name):
    print("调用了动态绑定的函数")
    self.name = name
if __name__ == '__main__':
    # 动态绑定一个属性
    A.kind = "人类"
    # 动态绑定一个函数
    A.set_name = set_name
    a = A(1)
    # 类访问动态绑定的属性
    print(A.kind)
    # 实例访问动态绑定的属性
    print(a.kind)
    # 类访问动态绑定的函数
    A.set_name(a,'123')
    # 实例访问动态绑定的函数
    a.set_name('321')


运行结果如下


人类
人类
调用了动态绑定的函数
调用了动态绑定的函数


实例动态绑定属性与函数,只对当前对象有效,对其他实例无效,需要用到一个MethodType类,代码示例如下:


from types import MethodType
class B:
    def __init__(self, id_):
        self.id_ = id_
# 定义一个用于动态绑定的函数
def set_name(self, name):
    print("调用了动态绑定的函数")
    self.name = name
if __name__ == '__main__':
    b_1 = B('1')
    # 动态为实例1绑定一个属性
    b_1.kind = "人类"
    # 动态为实例1绑定一个函数
    b_1.set_name = MethodType(set_name, b_1)
    # 实例1设置动态绑定的属性与函数
    print(b_1.kind)
    b_1.set_name('123')
    # 另一个类实例调用动态绑定的属性
    b_2 = B('2')
    print(b_2.kind)


运行结果如下


人类
Traceback (most recent call last):
调用了动态绑定的函数
  File "/Users/jay/Project/Python/Book/Chapter 9/9_7.py", line 30, in <module>
    print(b_2.kind)
AttributeError: 'B' object has no attribute 'kind'


相关文章
|
3天前
|
Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
37 0
|
3天前
|
索引 Python
python 格式化、set类型和class类基础知识练习(上)
python 格式化、set类型和class类基础知识练习
23 0
|
4天前
|
Python
python学习12-类对象和实例对象
python学习12-类对象和实例对象
|
25天前
|
Python
Python类(class)中self的理解
Python类(class)中self的理解
17 0
|
25天前
|
Python
Python类定义:从小白到专家的旅程
Python类定义:从小白到专家的旅程
7 0
|
25天前
|
Python
Python类与对象:深入解析与应用
本文介绍了Python中的核心概念——类和对象,以及它们在面向对象编程中的应用。类是用户定义的类型,描述具有相同属性和行为的对象集合;对象是类的实例,具备类的属性和方法。文章通过示例讲解了如何定义类、创建及使用对象,包括`__init__`方法、属性访问和方法调用。此外,还阐述了类的继承,允许子类继承父类的属性和方法并进行扩展。掌握这些概念有助于提升Python编程的效率和灵活性。
|
1月前
|
机器学习/深度学习 设计模式 开发者
python类用法(四)
python类用法(四)
17 0
|
1月前
|
Python
python类用法(三)
python类用法(三)
16 0
|
1月前
|
开发者 Python
Python对象和类
Python对象和类
9 0
|
Python 容器
【Python零基础入门篇 · 20】:可迭代对象和迭代器的转换、自定义迭代器类、异常类、生成器
【Python零基础入门篇 · 20】:可迭代对象和迭代器的转换、自定义迭代器类、异常类、生成器
103 0
【Python零基础入门篇 · 20】:可迭代对象和迭代器的转换、自定义迭代器类、异常类、生成器