Python面向对象(14成员成员修饰符)

news2024/9/21 16:30:56

目录

一.成员

1.变量

2.方法

3.属性

二.成员修饰符

一.成员

1.变量

  • 实例变量,属于对象,每个对象中各自维护自己的数据。

  • 类变量,属于类,可以被所有对象共享,一般用于给对象提供公共数据(类似于全局变量)。

class Person(object):
    country = "中国"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        # message = "{}-{}-{}".format(Person.country, self.name, self.age)
        message = "{}-{}-{}".format(self.country, self.name, self.age)
        print(message)

print(Person.country) # 中国


p1 = Person("武沛齐",20)
print(p1.name)
print(p1.age)
print(p1.country) # 中国

p1.show() # 中国-武沛齐-20

提示:当把每个对象中都存在的相同的示例变量时,可以选择把它放在类变量中,这样就可以避免对象中维护多个相同数据。

易错点 & 面试题

第一题:注意读和写的区别。

给实例变量重新赋值: 

class Person(object):
    country = "中国"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        message = "{}-{}-{}".format(self.country, self.name, self.age)
        print(message)

print(Person.country) # 中国

p1 = Person("武沛齐",20)
print(p1.name) # 武沛齐
print(p1.age) # 20
print(p1.country) # 中国
p1.show() # 中国-武沛齐-20

p1.name = "root"     # 在对象p1中讲name重置为root
p1.num = 19          # 在对象p1中新增实例变量 num=19
p1.country = "china" # 在对象p1中新增实例变量 country="china"

print(p1.country)   # china
print(Person.country) # 中国

给类变量重新赋值:

class Person(object):
    country = "中国"

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        message = "{}-{}-{}".format(self.country, self.name, self.age)
        print(message)

print(Person.country) # 中国

Person.country = "美国"


p1 = Person("武沛齐",20)
print(p1.name) # 武沛齐
print(p1.age) # 20
print(p1.country) # 美国

第二题:继承关系中的读写

class Base(object):
    country = "中国"


class Person(Base):

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        message = "{}-{}-{}".format(Person.country, self.name, self.age)
        # message = "{}-{}-{}".format(self.country, self.name, self.age)
        print(message)


# 读
print(Base.country) # 中国
print(Person.country) # 中国

obj = Person("武沛齐",19)
print(obj.country) # 中国

# 写
Base.country = "china"
Person.country = "泰国"
obj.country = "日本"

面试题:

class Parent(object):
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x, Child1.x, Child2.x) # 1 1 1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x) # 1 2 1
Parent.x = 3
print(Parent.x, Child1.x, Child2.x) # 3 2 3

2.方法

  • 绑定方法:默认有一个self参数,由对象进行调用(此时self就等于调用方法的这个对象)【对象&类均可调用】

  • 类方法:默认有一个cls参数,用类或对象都可以调用(此时cls就等于调用方法的这个类)【对象&类均可调用】

  • 静态方法:无默认参数,用类和对象都可以调用。【对象&类均可调用】

class Foo(object):

    def __init__(self, name,age):
        self.name = name
        self.age = age

    def f1(self):
        print("绑定方法", self.name)

    @classmethod
    def f2(cls):
        print("类方法", cls)

    @staticmethod
    def f3():
        print("静态方法")
        
# 绑定方法(对象)
obj = Foo("武沛齐",20)
obj.f1() # Foo.f1(obj)


# 类方法
Foo.f2()  # cls就是当前调用这个方法的类。(类)
obj.f2()  # cls就是当前调用这个方法的对象的类。


# 静态方法
Foo.f3()  # 类执行执行方法(类)
obj.f3()  # 对象执行执行方法

在Python中比较灵活,方法都可以通过对象和类进行调用;而在java、c#等语言中,绑定方法只能由对象调用;类方法或静态方法只能由类调用。

import os
import requests

class Download(object):
    def __init__(self, folder_path):
        self.folder_path = folder_path

    @staticmethod
    def download_dou_yin():
        # 下载抖音
        res = requests.get('.....')

        with open("xxx.mp4", mode='wb') as f:
            f.write(res.content)

    def download_dou_yin_2(self):
        # 下载抖音
        res = requests.get('.....')
        path = os.path.join(self.folder_path, 'xxx.mp4')
        with open(path, mode='wb') as f:
            f.write(res.content)

obj = Download("video")
obj.download_dou_yin()

3.属性

属性其实是由绑定方法 + 特殊装饰器 组合创造出来的,让我们以后在调用方法时可以不加括号,例如:

class Foo(object):
    def __init__(self, name):
        self.name = name
    def f1(self):
        return 123

    @property
    def f2(self):
        return 123

obj = Foo("武沛齐")
v1 = obj.f1()
print(v1)
v2 = obj.f2
print(v2)
#123
#123

关于属性的编写有两种方式:

  • 方式一,基于装饰器

class C(object):
    
    @property
    def x(self):
        pass
    
    @x.setter
    def x(self, value):
        pass
    
    @x.deleter
    def x(self):
		pass
        
obj = C()

obj.x
obj.x = 123
del obj.x

方式二,基于定义变量

class C(object):
    
    def getx(self): 
		pass
    
    def setx(self, value): 
		pass
        
    def delx(self): 
		pass
        
    x = property(getx, setx, delx, "I'm the 'x' property.")
    
obj = C()

obj.x
obj.x = 123
del obj.x

写在最后,对属性进行一个补充:

由于属性和实例变量的调用方式相同,所以在编写时需要注意:属性名称 不要 实例变量 重名。一旦重名,可能就会有报错。

class Foo(object):

    def __init__(self, name, age):
        self.name = name  # 报错,错认为你想要调用 @name.setter 装饰的方法。
        self.age = age

    @property
    def name(self):
        return "{}-{}".format(self.name, self.age)

obj = Foo("武沛齐", 123)
class Foo(object):
    def __init__(self, name, age):
        self.name = name 
        self.age = age

    @property
    def name(self):
        return "{}-{}".format(self.name, self.age) # 报错,循环调用自己(直到层级太深报错)

    @name.setter
    def name(self, value):
        print(value)

obj = Foo("武沛齐", 123)
print(obj.name)

如果真的想要在名称上创建一些关系,可以让实例变量加上一个下划线。  

class Foo(object):
    def __init__(self, name, age):
        self._name = name
        self.age = age

    @property
    def name(self):
        return "{}-{}".format(self._name, self.age)

obj = Foo("武沛齐", 123)
print(obj._name)
print(obj.name)

二.成员修饰符

Python中成员的修饰符就是指的是:公有、私有。

  • 公有,在任何地方都可以调用这个成员。

  • 私有,只有在类的内部才可以调用改成员(成员是以两个下划线开头,则表示该成员为私有)。

示例1:

class Foo(object):

    def __init__(self, name, age):
        self.__name = name
        self.age = age

    def get_data(self):
        return self.__name

    def get_age(self):
        return self.age


obj = Foo("武沛齐", 123)


# 公有成员
print(obj.age)
v1 = self.get_age()
print(v1)

# 私有成员
# print(obj.__name) # 错误,由于是私有成员,只能在类中进行使用。
v2 = obj.get_data()
print(v2)

示例2:

class Foo(object):

    def get_age(self):
        print("公有的get_age")

    def __get_data(self):
        print("私有的__get_data方法")

    def proxy(self):
        print("公有的proxy")
        self.__get_data()


obj = Foo()
obj.get_age()

obj.proxy()

示例3:

class Foo(object):

    @property
    def __name(self):
        print("公有的get_age")

    @property
    def proxy(self):
        print("公有的proxy")
        self.__name
        return 1

obj = Foo()
v1 = obj.proxy
print(v1)

特别提醒:父类中的私有成员,子类无法继承。

class Base(object):

    def __data(self):
        print("base.__data")

    def num(self):
        print("base.num")

class Foo(Base):

    def func(self):
        self.num()
        self.__data() # # 不允许执行父类中的私有方法

obj = Foo()
obj.func()
class Base(object):

    def __data(self):
        print("base.__data")

    def num(self):
        print("base.num")
        self.__data()  # 不允许执行父类中的私有方法

class Foo(Base):

    def func(self):
        self.num()

obj = Foo()
obj.func()

写在最后,按理说私有成员是无法被外部调用,但如果用一些特殊的语法也可以(Flask源码中有这种写法,大家写代码不推荐这样写)。

class Foo(object):

    def __init__(self):
        self.__num = 123
        self.age = 19

    def __msg(self):
        print(1234)


obj = Foo()
print(obj.age)
print(obj._Foo__num)
obj._Foo__msg()

成员是否可以作为独立的功能暴露给外部,让外部调用并使用。

  • 可以,公有。

  • 不可以,内部其他放的一个辅助,私有。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2111562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[机器学习]线性回归算法

1 线性回归简介 概念:利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。 weight:权重;bias 偏置 线性回归分类&#xf…

代码随想录算法训练营_day37

题目信息 518. 零钱兑换 II 题目链接: https://leetcode.cn/problems/coin-change-ii/description/题目描述: 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑…

pgrx在docker中问题无法解决

前面写了一系列pgrx开发结合docker postgres,但是当程序写的很大的时候,发现本地安装没有问题,docker里面可能有libc6 2.33 报错以及下面错误: 但是,在本地安装的pg中,没有这问题: 至于为什么,我查了很多,比如docker版本问题blablabla,都不重要了,按照所有建议的方法都没有解决…

示波器知识 | 什么是示波器?模拟和数字示波器区别?

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 1、什么是示波器? 示波器是一种电子测试和测量仪器,以 X-Y 图的形式以图形方式显示电信号。在这里&…

【LeetCode】:面试题 16.05. 阶乘尾数

🎁个人主页:我们的五年 🔍系列专栏:C课程学习 🎉欢迎大家点赞👍评论📝收藏⭐文章 好久没有写文章了,今天碰见了一道有趣的题目,写下来分享一下。 🏆1.问题描…

智能新纪元:GPT-Next引领的AI革命及其跨领域应用

GPT-Next:性能的百倍提升 在当今这个科技日新月异的时代,人工智能(AI)无疑是最具活力和变革性的领域之一。最近,OpenAI在KDDI峰会上宣布了一项激动人心的消息:他们即将推出名为“GPT-Next”的新一代语言模…

【Matplotlib】利用Python进行绘图!(python数据分析与可视化)

文章开始前打个小广告——分享一份Python学习大礼包(激活码安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程)点击领取,100%免费! 【Matplotlib】 教程&…

MySQL(CRUD)

MySQL mysql -u root -ply MySQL的三层结构 1.安装MySQL数据库本质就是在主机安装一个数据库管理系统(DBMS),这个管理程序可以管理多个数据库. 2.一个数据库中可以创建多个表,以保存数据 SQL语句分类 1.DDL:数据定义语句[create 表,库] 2.DML:数据操作语句[增加insert,修改…

【杂记】裂脑人实验和语言模型幻觉

【杂记】裂脑人实验和语言模型幻觉 模型的自主意识在哪里,人的自我认知在哪里?自然而然的,“裂脑人” 这个词突然出现在我脑海里。然后随意翻了翻相关的文章,觉得这个问题和目前大模型面临的幻觉问题也高度相关,遂随笔…

一图打尽C++内存分区(分段)

一图打尽C内存分区(分段) 直接上图: 栈区(Stack Segment): 位于内存的高地址部分。用于存储函数调用时的局部变量、函数参数和返回地址。内存地址从高向低增长。 堆区(Heap Segment): 位于栈区…

人工智能的12个不为人知的秘密

随着人工智能技术在各行业的应用越来越广泛,IT领导者需要了解如何采用人工智能技术收集商业见解的秘密。 人类一直梦想着有一个无所不知、无所不能的精灵为自己提供帮助。如今需要感谢计算机科学家的不断探索和努力,将在人工智能领域找到这个答案&#x…

HTMX:用HTML属性实现AJAX、CSS过渡和WebSockets

前言 在现代 Web 开发中,用户界面的交互性和响应性是至关重要的。 用户期望网站和应用程序能够即时响应他们的操作,提供流畅和直观的体验。 传统的 JavaScript 库虽然功能强大,但往往伴随着复杂的配置和庞大的文件大小,这可能会…

怎么做PPT?10个做PPT必备的实用技巧,附3款AI制作PPT软件推荐!

在视觉化表达成为主流的当下,对于商业演示、学术报告还是课堂教学等场景,一份精心准备的PPT,能让你的观点更具说服力,更容易被观众所接受。 但不可否认的是,对许多人来说,制作一份既专业又吸引人的PPT幻灯…

浅谈城市地铁智能照明系统的能耗分析及节能措施

0引言 中国近40年经济快速增长,面临快速城市化挑战。城市轨道交通成为发达国家主要交通方式。2016年,43个城市获建设许可,比2012年多8个。"十三五"期间,新建城市轨道交通5357公里,年均1071公里,…

第23周:使用Word2vec实现文本分类

目录 前言 一、数据预处理 1.1 加载数据 1.2 构建词典 1.3 生成数据批次和迭代器 二、模型构建 2.1 搭建模型 2.2 初始化模型 2.3 定义训练和评估函数 三、训练模型 3.1 拆分数据集并运行模型 3.2 测试指定数据 总结 前言 🍨 本文为[🔗365天…

贪吃蛇游戏:增加暂停按钮,每次增加10分蛇会变化

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>贪吃蛇游戏</title> </head> <st…

奇安信椒图--服务器安全管理系统(云锁)

奇安信椒图–服务器安全管理系统&#xff08;云锁&#xff09; 椒图 奇安信服务器安全管理系统是一款符合Gartner定义的CWPP&#xff08;云工作负载保护平台&#xff09;标准、EDR&#xff08;终端检测与响应&#xff09;、EPP终端保护平台&#xff08;终端保护平台&#xff…

山东济南最厉害的改名大师颜廷利:中国当代最伟大的哲学家之一

山东济南最厉害的改名大师颜廷利&#xff1a;中国当代最伟大的哲学家之一 颜廷利教授的哲学思想主要集中在《升命学说》中&#xff0c;强调奉献与无私奉献的重要性&#xff0c;认为金钱利益交易是现代社会的一个问题&#xff0c;并提出了一个理想的文明社会模型&#xff0c;其…

C++---由优先级队列认识仿函数

文章目录 一、优先级队列是什么&#xff1f; 二、如何使用优先级队列 1、优先级队列容器用法 2、为什么容器本身无序&#xff1f; 三、什么是仿函数&#xff1f; 1. 什么是仿函数&#xff1f; 2. 仿函数的优势 四、仿函数如何使用&#xff1f; 1、重载operator()函数 2、运用第…

分支管理

目录 创建分支 切换分支 合并分支 删除分支 合并冲突 创建分支 git branch [分支]指令 创建新的分⽀后&#xff0c;Git 新建了⼀个指针叫dev&#xff0c; * 表⽰当前 HEAD 指向的分⽀是 master 分⽀。另外&#xff0c;可以通过⽬录结构发现&#xff0c;新的 dev 分⽀…