RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1591636
Accepted
extract
extract
Asked:2024-08-23 04:44:41 +0000 UTC2024-08-23 04:44:41 +0000 UTC 2024-08-23 04:44:41 +0000 UTC

我不明白哪个变量/属性正在改变,因为我想得到一个 AttributeError

  • 772
from dotenv import load_dotenv
import os
from googleapiclient.discovery import build
import json
load_dotenv()


class Channel:
    """Класс для ютуб-канала"""

    youtube = build('youtube', 'v3', developerKey=os.getenv("API_YOU_TUBE"))

    def __init__(self, channel_id: str) -> None:
        """Экземпляр инициализируется id канала. Дальше все данные будут подтягиваться по API."""
        self.__channel_id = channel_id
        self.title = self.get_data_init()["items"][0]["snippet"]["title"]
        self.description = self.get_data_init()["items"][0]["snippet"]["description"]
        self.url = "https://www.youtube.com/channel/" + self.get_data_init()["items"][0]["id"]
        self.subscriber_count = self.get_data_init()["items"][0]["statistics"]["subscriberCount"]
        self.video_count = self.get_data_init()["items"][0]["statistics"]["videoCount"]
        self.view_count = self.get_data_init()["items"][0]["statistics"]["viewCount"]


    def print_info(self) -> None:
        """Выводит в консоль информацию о канале."""
        channel = self.youtube.channels().list(id=self.__channel_id, part='snippet,statistics').execute()
        print(channel)

    def get_data_init(self):
        channel = self.youtube.channels().list(id=self.__channel_id, part='snippet,statistics').execute()
        return channel

    @staticmethod
    def get_service():
        return Channel.youtube

    def to_json(self, data):
        with open(data, "w") as f:
            f.write(str(self.get_data_init()))

    def __repr__(self):
        return f"{self.__channel_id}, {self.subscriber_count}"

moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A')
moscowpython.__channel_id = 'Новое название'
print(moscowpython.__channel_id)
print(moscowpython)

# не выдает никаких ошибок, хотя должна AttributeError```

Изменено:
 вот так выдает ошибку:
moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A')
print(moscowpython.__channel_id)
moscowpython.__channel_id = 'Новое название'
print(moscowpython.__channel_id)
print(moscowpython)

а вот так нет:

moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A')
# print(moscowpython.__channel_id)
moscowpython.__channel_id = 'Новое название'
print(moscowpython.__channel_id)
print(moscowpython)
python
  • 2 2 个回答
  • 53 Views

2 个回答

  • Voted
  1. Best Answer
    Amgarak
    2024-08-23T20:52:15Z2024-08-23T20:52:15Z

    让我们首先简化示例并删除所有不必要的内容:

    class Channel:
    
        def __init__(self, channel_id: str) -> None:
            self.__channel_id = channel_id
            
        def test(self):
            print(self.__channel_id )
            
    
    moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A')
    print(dir(moscowpython))
    moscowpython.__channel_id = 'Новое название'
    print(moscowpython.__channel_id)
    moscowpython.test()
    print(dir(moscowpython))
    

    结论:

    ['_Channel__channel_id', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test']
    Новое название
    UC-OVMPlMA3-YCIeg4z5z23A
    ['_Channel__channel_id', '__channel_id', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test']
    
    [Program finished]
    

    Python中的dir()函数是一个内置函数,它返回对象的所有属性和方法的列表。

    现在请注意第一个打印对象列表,特别是_Channel__channel_id,这是您的私有属性。

    它也出现在第二个打印对象列表中,因此我们没有重新定义它,这可以使用test方法轻松检查。


    在我们的示例中,该属性在Channel__channel_id类中被定义为private。Python中的私有属性是使用一种名为name mangling的机制来处理的,该机制会重命名属性以防止它们被意外覆盖或在类外部访问。

    当您声明带有双下划线的属性时,Python会自动以_ИмяКласса__ИмяАтрибута.在我们的例子中,__channel_id属性将被重命名为_Channel__channel_id。

    这样,如果您尝试更改 的值moscowpython.__channel_id(如我们的示例中所示),Python不会抛出错误,因为它不会将其视为__channel_id私有属性。相反,它只是__channel_id在moscowpython对象中创建一个新属性,该属性将作为常规属性使用,但它不再是在类内部定义的属性,因为我们的属性已经看起来像这样 - _Channel__channel_id。


    您可以稍微扭曲一下这个想法,这样您就无法通过__重写该类的魔术方法之一来创建属性:

    class Channel:
    
        def __init__(self, channel_id: str) -> None:
            self.__channel_id = channel_id
            
        def __setattr__(self, name, value):
            # Если имя атрибута начинается с двойного подчеркивания, выбрасываем исключение
            if name.startswith('__'):
                raise AttributeError(f"Создание атрибута '{name}' запрещено")
            super().__setattr__(name, value)
    
    moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A')
    
    moscowpython.__channel_id = 'Новое название'
    

    结论:

    Traceback (most recent call last):
      File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 31, in <module>
        start(fakepyfile,mainpyfile)
      File "/data/user/0/ru.iiec.pydroid3/files/accomp_files/iiec_run/iiec_run.py", line 30, in start
        exec(open(mainpyfile).read(),  __main__.__dict__)
      File "<string>", line 18, in <module>
      File "<string>", line 9, in __setattr__
    AttributeError: Создание атрибута '__channel_id' запрещено
    
    [Program finished]
    

    因此,这就是捕获错误的方法:

    try:
        moscowpython.__channel_id = 'Новое название'
    except AttributeError as e:
        print(e) 
    
    • 1
  2. Artem
    2024-08-23T11:02:51Z2024-08-23T11:02:51Z

    该错误与从类调用对象字段AttributeError有关__channel_idChannel

    错误的:

    moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A') # Создание объекта класса
    print(moscowpython.__channel_id) # Вызов несуществующего поля
    

    正确的:

    moscowpython = Channel('UC-OVMPlMA3-YCIeg4z5z23A') # Создание объекта класса
    moscowpython.__channel_id = 'Новое название' # Присваивание значения полю
    print(moscowpython.__channel_id) # Вызов существующего поля
    
    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5