猪行天下之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'


相关文章
|
2月前
|
索引 Python
python-类属性操作
【10月更文挑战第11天】 python类属性操作列举
22 1
|
2月前
|
Java C++ Python
Python基础---类
【10月更文挑战第10天】Python类的定义
26 2
|
2月前
|
设计模式 开发者 Python
Python类里引用其他类
Python类里引用其他类
|
2月前
|
设计模式 开发者 Python
Python 类中引用其他类的实现详解
Python 类中引用其他类的实现详解
41 1
WK
|
2月前
|
Python
Python类命名
在Python编程中,类命名至关重要,影响代码的可读性和维护性。建议使用大写驼峰命名法(如Employee),确保名称简洁且具描述性,避免使用内置类型名及单字母或数字开头,遵循PEP 8风格指南,保持项目内命名风格一致。
WK
14 0
|
2月前
|
程序员 开发者 Python
深度解析Python中的元编程:从装饰器到自定义类创建工具
【10月更文挑战第5天】在现代软件开发中,元编程是一种高级技术,它允许程序员编写能够生成或修改其他程序的代码。这使得开发者可以更灵活地控制和扩展他们的应用逻辑。Python作为一种动态类型语言,提供了丰富的元编程特性,如装饰器、元类以及动态函数和类的创建等。本文将深入探讨这些特性,并通过具体的代码示例来展示如何有效地利用它们。
39 0
|
2月前
|
Python
Python中的类(一)
Python中的类(一)
|
2月前
|
Python
Python中的类(一)
Python中的类(一)
|
2月前
|
Python
Python中的类(二)
Python中的类(二)
|
2月前
|
开发者 Python
Python类和子类的小示例:建模农场
Python类和子类的小示例:建模农场