찾다
백엔드 개발파이썬 튜토리얼Python 설명자의 의미 소개

'디스크립터'라는 개념을 자주 들어보셨겠지만, 대부분의 프로그래머들은 거의 사용하지 않기 때문에 그 원리를 명확하게 이해하지 못할 수도 있습니다. python 동영상 튜토리얼 칼럼에서 자세히 소개하겠습니다. ):

python 비디오 튜토리얼

Python 설명자의 의미 소개

하지만 경력을 쌓고 Python 사용에 더욱 능숙해지고 싶다면 여전히 설명자를 해야 한다고 생각합니다. 여러분의 향후 개발에 큰 도움이 될 것이며, 향후 Python 디자인에 대해 더 깊이 이해하는 데도 도움이 될 것입니다. 개발 과정에서 디스크립터를 직접 사용하지는 않았지만, 하위 레벨에서는 매우 자주 사용됩니다. 예를 들어 다음과 같습니다:

설명자란 무엇인가요?

描述符的这个概念有一个清晰的了解,这对于你以后的发展有着巨大的帮助,也有利于你将来更深层次的python设计的理解。

尽管在开发的过程中,我们没有直接的使用过描述符,但是它在底层的运用却是十分频繁的存在。例如下面的这些:

  • functionbound methodunbound method
  • 装是器propertystaticmethodclassmethod
    这些是不是都很熟悉?
    其实这些都与描述符有着千丝万缕的联系,这样吧,我们通过下面的文章来探讨一下描述符背后的工作原理吧。

什么是描述符?

在我们了解什么是描述符前,我们可以先找一个例子来看一下

class A:
    x = 10print(A.x) # 10

这个例子很简单,我们先在类A中定义一个类属性x,然后得出它的值。
除了这种直接定义类属性的方法外,我们还可以这样去定义一个类属性:

class Ten:
    def __get__(self, obj, objtype=None):
        return 10class A:
    x = Ten()   # 属性换成了一个类print(A.x) # 10

我们可以发现,这回的类属性x不是一个具体的值了,而是一个类Ten,通过这个Ten定义了一个__get__方法,返回具体的值。

因此可得出:在python中,我们可以把一个类的属性,托管给一个类,而这样的属性就是一个描述符
简而言之,描述符是一个绑定行为属性

而这又有着什么意思呢?
回想,我们在开发时,一般情况下,会将行为叫做什么?行为即一个方法。

所以我们也可以将描述符理解为:对象的属性并非一个具体的值,而是交给了一个方法去定义。

可以想像一下,如果我们用一个方法去定义一个属性,这么做有什么好处?

有了方法,我们就可以在方法内实现自己的逻辑,最简单的,我们可以根据不同的条件,在方法内给属性赋予不同的值,就像下面这样:

class Age:
    def __get__(self, obj, objtype=None):
        if obj.name == 'zhangsan':
            return 20
        elif obj.name == 'lisi':
            return 25
        else:
            return ValueError("unknow")class Person:

    age = Age()

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

p1 = Person('zhangsan')print(p1.age)   # 20p2 = Person('lisi')print(p2.age)   # 25p3 = Person('wangwu')print(p3.age)   # unknow

这个例子中,age 类属性被另一个类托管了,在这个类的 __get__ 中,它会根据 Person 类的属性 name,决定 age 是什么值。

通过这样一个例子,我们可以看到,通过描述符的使用,我们可以轻易地改变一个类属性的定义方式。

描述符协议

了解了描述符的定义,现在我们把重点放到托管属性的类上。

其实,一个类属性想要托管给一个类,这个类内部实现的方法不能是随便定义的,它必须遵守「描述符协议」,也就是要实现以下几个方法:

  • __get__(self, obj, type=None) -> value
  • __set__(self, obj, value) -> None
  • __delete__(self, obj) -> None

只要是实现了以上几个方法的其中一个,那么这个类属性就可以称作描述符。

另外,描述符又可以分为「数据描述符」和「非数据描述符」:

  • 只定义了 __get___,叫做非数据描述符
  • 除了定义 __get__ 之外,还定义了 __set____delete__,叫做数据描述符

它们两者有什么区别,我会在下面详述。

现在我们来看一个包含 __get____set__ 方法的描述符例子:

# coding: utf8class Age:

    def __init__(self, value=20):
        self.value = value

    def __get__(self, obj, type=None):
        print('call __get__: obj: %s type: %s' % (obj, type))
        return self.value

    def __set__(self, obj, value):
        if value  type: <class># 20print(Person.age)# call __get__: obj: None type: <class># 20p1.age = 25# call __set__: obj: <__main__.person> value: 25print(p1.age)# call __get__: obj: <__main__.person> type: <class># 25p1.age = -1# ValueError: age must be greater than 0</class></__main__.person></__main__.person></class></class>

在这例子中,类属性 age 是一个描述符,它的值取决于 Age 类。

从输出结果来看,当我们获取或修改 age 属性时,调用了 Age__get____set__

설명자가 무엇인지 이해하기 전에 먼저 예제를 살펴보겠습니다.🎜
def getattr_hook(obj, name):
    try:
        return obj.__getattribute__(name)
    except AttributeError:
        if not hasattr(type(obj), '__getattr__'):
            raise    return type(obj).__getattr__(obj, name)
🎜이 예제는 매우 간단합니다. 먼저 🎜class 속성🎜A >x를 선택한 다음 해당 값을 가져옵니다.
클래스 속성을 직접 정의하는 이 방법 외에도 다음과 같이 클래스 속성을 정의할 수도 있습니다. 🎜
# 获取一个对象的属性
def __getattribute__(obj, name):
    null = object()
    # 对象的类型 也就是实例的类
    objtype = type(obj)
    # 从这个类中获取指定属性
    cls_var = getattr(objtype, name, null)
    # 如果这个类实现了描述符协议
    descr_get = getattr(type(cls_var), '__get__', null)
    if descr_get is not null:
        if (hasattr(type(cls_var), '__set__')
            or hasattr(type(cls_var), '__delete__')):
            # 优先从数据描述符中获取属性            return descr_get(cls_var, obj, objtype)
    # 从实例中获取属性    if hasattr(obj, '__dict__') and name in vars(obj):
        return vars(obj)[name]
    # 从非数据描述符获取属性    if descr_get is not null:
        return descr_get(cls_var, obj, objtype)
    # 从类中获取属性    if cls_var is not null:
        return cls_var
    # 抛出 AttributeError 会触发调用 __getattr__
    raise AttributeError(name)
🎜이번에는 클래스 속성 x가 특정 값이 아니라는 것을 알 수 있습니다. 대신 Ten 클래스입니다. 이 Ten은 특정 값을 반환하는 __get__ 메서드를 정의합니다. 🎜🎜결론은 다음과 같습니다. Python에서는 🎜클래스의 속성을 클래스에 호스팅할 수 있으며 이러한 속성은 설명자🎜
간단히 말하면 설명자입니다. 바인딩 동작 속성입니다🎜🎜이게 무슨 뜻인가요?
우리가 개발할 때 일반적으로 행동을 무엇이라고 부르나요? 행동은 메소드입니다. 🎜🎜그래서 descriptor를 다음과 같이 이해할 수도 있습니다. 🎜객체의 속성은 특정 값이 아니라 메서드에 의해 정의됩니다. 🎜🎜🎜속성을 정의하는 방법을 사용하면 어떤 이점이 있는지 상상할 수 있습니까? 🎜🎜메서드를 사용하면 메서드 내에서 자체 논리를 구현할 수 있습니다. 가장 간단한 방법은 다음과 같이 다양한 조건에 따라 메서드 내의 속성에 다양한 값을 할당할 수 있다는 것입니다. code>age 클래스 속성은 이 클래스의 __get__에서 호스팅되며 Person 클래스 속성 name을 기반으로 합니다. >는 age 값이 무엇인지 결정합니다. 🎜🎜이러한 예를 통해 설명자를 사용하면 클래스 속성이 정의되는 방식을 쉽게 변경할 수 있음을 알 수 있습니다. 🎜🎜🎜설명자 프로토콜🎜🎜🎜설명자의 정의를 이해했으므로 이제 관리 속성 클래스에 중점을 둡니다. 🎜🎜실제로 클래스 속성을 클래스에서 호스팅하려면 이 클래스 내부에 구현된 메서드를 임의로 정의할 수 없습니다. 즉, 다음 메서드를 구현해야 합니다. 🎜
  • __get__(self, obj, type=None) -> 값
  • __set__(self, obj, value) -> > li>
  • __delete__(self, obj) -> None
🎜위 메소드 중 하나가 구현되는 한 이 클래스 속성은 다음과 같습니다. 설명자라고 할 수 있습니다. 🎜🎜또한 설명자는 "데이터 설명자"와 "비데이터 설명자"로 나눌 수 있습니다. 🎜
  • 비데이터 설명자라고 하는 __get___만 정의됩니다. li >
  • __get__ 정의 외에도 __set__ 또는 __delete__도 정의되어 데이터 설명자라고 합니다.
🎜그들 사이의 차이점은 무엇입니까? 아래에서 자세히 설명하겠습니다. 🎜🎜이제 __get____set__ 메서드가 포함된 설명자의 예를 살펴보겠습니다. 🎜
type(a).__dict__['b'].__get__(a, type(a))复制代码
🎜이 예에서 클래스 속성 age는 값이 Age 클래스에 따라 달라지는 설명자입니다. 🎜🎜출력 결과에 따르면 age 속성을 ​​얻거나 수정할 때 Age__get____set__이 호출됩니다. 코드> 방법: 🎜<ul> <li>当调用 <code>p1.age 时,__get__ 被调用,参数 objPerson 实例,typetype(Person)
  • 当调用 Person.age 时,__get__ 被调用,参数 objNonetypetype(Person)
  • 当调用 p1.age = 25时,__set__ 被调用,参数 objPerson 实例,value 是25
  • 当调用 p1.age = -1时,__set__ 没有通过校验,抛出 ValueError
  • 其中,调用 __set__ 传入的参数,我们比较容易理解,但是对于 __get__ 方法,通过类或实例调用,传入的参数是不同的,这是为什么?

    这就需要我们了解一下描述符的工作原理。

    描述符的工作原理

    要解释描述符的工作原理,首先我们需要先从属性的访问说起。

    在开发时,不知道你有没有想过这样一个问题:通常我们写这样的代码 a.b,其背后到底发生了什么?

    这里的 ab 可能存在以下情况:

    1. a 可能是一个类,也可能是一个实例,我们这里统称为对象
    2. b 可能是一个属性,也可能是一个方法,方法其实也可以看做是类的属性

    其实,无论是以上哪种情况,在 Python 中,都有一个统一的调用逻辑:

    1. 先调用 __getattribute__ 尝试获得结果
    2. 如果没有结果,调用 __getattr__

    用代码表示就是下面这样:

    def getattr_hook(obj, name):
        try:
            return obj.__getattribute__(name)
        except AttributeError:
            if not hasattr(type(obj), '__getattr__'):
                raise    return type(obj).__getattr__(obj, name)

    我们这里需要重点关注一下 __getattribute__,因为它是所有属性查找的入口,它内部实现的属性查找顺序是这样的:

    1. 要查找的属性,在类中是否是一个描述符
    2. 如果是描述符,再检查它是否是一个数据描述符
    3. 如果是数据描述符,则调用数据描述符的 __get__
    4. 如果不是数据描述符,则从 __dict__ 中查找
    5. 如果 __dict__ 中查找不到,再看它是否是一个非数据描述符
    6. 如果是非数据描述符,则调用非数据描述符的 __get__
    7. 如果也不是一个非数据描述符,则从类属性中查找
    8. 如果类中也没有这个属性,抛出 AttributeError 异常

    写成代码就是下面这样:

    # 获取一个对象的属性
    def __getattribute__(obj, name):
        null = object()
        # 对象的类型 也就是实例的类
        objtype = type(obj)
        # 从这个类中获取指定属性
        cls_var = getattr(objtype, name, null)
        # 如果这个类实现了描述符协议
        descr_get = getattr(type(cls_var), '__get__', null)
        if descr_get is not null:
            if (hasattr(type(cls_var), '__set__')
                or hasattr(type(cls_var), '__delete__')):
                # 优先从数据描述符中获取属性            return descr_get(cls_var, obj, objtype)
        # 从实例中获取属性    if hasattr(obj, '__dict__') and name in vars(obj):
            return vars(obj)[name]
        # 从非数据描述符获取属性    if descr_get is not null:
            return descr_get(cls_var, obj, objtype)
        # 从类中获取属性    if cls_var is not null:
            return cls_var
        # 抛出 AttributeError 会触发调用 __getattr__
        raise AttributeError(name)

    如果不好理解,你最好写一个程序测试一下,观察各种情况下的属性的查找顺序。

    到这里我们可以看到,在一个对象中查找一个属性,都是先从 __getattribute__ 开始的。

    __getattribute__ 中,它会检查这个类属性是否是一个描述符,如果是一个描述符,那么就会调用它的 __get__ 方法。但具体的调用细节和传入的参数是下面这样的:

    • 如果 a 是一个实例,调用细节为:
    type(a).__dict__['b'].__get__(a, type(a))复制代码
    • 如果 a 是一个,调用细节为:
    a.__dict__['b'].__get__(None, a)复制代码

    所以我们就能看到上面例子输出的结果。

    数据描述符和非数据描述符

    了解了描述符的工作原理,我们继续来看数据描述符和非数据描述符的区别。

    从定义上来看,它们的区别是:

    • 只定义了 __get___,叫做非数据描述符
    • 除了定义 __get__ 之外,还定义了 __set____delete__,叫做数据描述符

    此外,我们从上面描述符调用的顺序可以看到,在对象中查找属性时,数据描述符要优先于非数据描述符调用。

    在之前的例子中,我们定义了 __get____set__,所以那些类属性都是数据描述符

    我们再来看一个非数据描述符的例子:

    class A:
    
        def __init__(self):
            self.foo = 'abc'
    
        def foo(self):
            return 'xyz'print(A().foo)  # 输出什么?
    复制代码

    这段代码,我们定义了一个相同名字的属性和方法 foo,如果现在执行 A().foo,你觉得会输出什么结果?

    答案是 abc

    为什么打印的是实例属性 foo 的值,而不是方法 foo 呢?

    这就和非数据描述符有关系了。

    我们执行 dir(A.foo),观察结果:

    print(dir(A.foo))# [... '__get__', '__getattribute__', ...]复制代码

    看到了吗?Afoo 方法其实实现了 __get__,我们在上面的分析已经得知:只定义 __get__ 方法的对象,它其实是一个非数据描述符,也就是说,我们在类中定义的方法,其实本身就是一个非数据描述符。

    所以,在一个类中,如果存在相同名字的属性和方法,按照上面所讲的 __getattribute__ 中查找属性的顺序,这个属性就会优先从实例中获取,如果实例中不存在,才会从非数据描述符中获取,所以在这里优先查找的是实例属性 foo 的值。

    到这里我们可以总结一下关于描述符的相关知识点:

    • 描述符必须是一个类属性
    • __getattribute__ 是查找一个属性(方法)的入口
    • __getattribute__ 定义了一个属性(方法)的查找顺序:数据描述符、实例属性、非数据描述符、类属性
    • 如果我们重写了 __getattribute__ 方法,会阻止描述符的调用
    • 所有方法其实都是一个非数据描述符,因为它定义了 __get__

    描述符的使用场景

    了解了描述符的工作原理,那描述符一般用在哪些业务场景中呢?

    在这里我用描述符实现了一个属性校验器,你可以参考这个例子,在类似的场景中去使用它。

    首先我们定义一个校验基类 Validator,在 __set__ 方法中先调用 validate 方法校验属性是否符合要求,然后再对属性进行赋值。

    class Validator:
    
        def __init__(self):
            self.data = {}
    
        def __get__(self, obj, objtype=None):
            return self.data[obj]
    
        def __set__(self, obj, value):
            # 校验通过后再赋值
            self.validate(value)
            self.data[obj] = value
    
        def validate(self, value):
            pass    
    复制代码

    接下来,我们定义两个校验类,继承 Validator,然后实现自己的校验逻辑。

    class Number(Validator):
    
        def __init__(self, minvalue=None, maxvalue=None):
            super(Number, self).__init__()
            self.minvalue = minvalue
            self.maxvalue = maxvalue
    
        def validate(self, value):
            if not isinstance(value, (int, float)):
                raise TypeError(f'Expected {value!r} to be an int or float')
            if self.minvalue is not None and value  self.maxvalue:
                raise ValueError(
                    f'Expected {value!r} to be no more than {self.maxvalue!r}'
                )class String(Validator):
    
        def __init__(self, minsize=None, maxsize=None):
            super(String, self).__init__()
            self.minsize = minsize
            self.maxsize = maxsize
    
        def validate(self, value):
            if not isinstance(value, str):
                raise TypeError(f'Expected {value!r} to be an str')
            if self.minsize is not None and len(value)  self.maxsize:
                raise ValueError(
                    f'Expected {value!r} to be no bigger than {self.maxsize!r}'
                )复制代码

    最后,我们使用这个校验类:

    class Person:
    
        # 定义属性的校验规则 内部用描述符实现
        name = String(minsize=3, maxsize=10)
        age = Number(minvalue=1, maxvalue=120)
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    # 属性符合规则
    p1 = Person('zhangsan', 20)print(p1.name, p1.age)# 属性不符合规则
    p2 = person('a', 20)# ValueError: Expected 'a' to be no smaller than 3p3 = Person('zhangsan', -1)# ValueError: Expected -1 to be at least 1复制代码

    现在,当我们对 Person 实例进行初始化时,就可以校验这些属性是否符合预定义的规则了。

    function与method

    我们再来看一下,在开发时经常看到的 functionunbound methodbound method 它们之间到底有什么区别?

    来看下面这段代码:

    class A:
    
        def foo(self):
            return 'xyz'print(A.__dict__['foo']) # <function>print(A.foo)     # <unbound>print(A().foo)   # <bound>>复制代码</bound></unbound></function>

    从结果我们可以看出它们的区别:

    • function 准确来说就是一个函数,并且它实现了 __get__ 方法,因此每一个 function 都是一个非数据描述符,而在类中会把 function 放到 __dict__ 中存储
    • function 被实例调用时,它是一个 bound method
    • function 被类调用时, 它是一个 unbound method

    function 是一个非数据描述符,我们之前已经讲到了。

    bound methodunbound method 的区别就在于调用方的类型是什么,如果是一个实例,那么这个 function 就是一个 bound method,否则它是一个 unbound method

    property/staticmethod/classmethod

    我们再来看 propertystaticmethodclassmethod

    这些装饰器的实现,默认是 C 来实现的。

    其实,我们也可以直接利用 Python 描述符的特性来实现这些装饰器,

    property 的 Python 版实现:

    class property:
    
        def __init__(self, fget=None, fset=None, fdel=None, doc=None):
            self.fget = fget
            self.fset = fset
            self.fdel = fdel
            self.__doc__ = doc
    
        def __get__(self, obj, objtype=None):
            if obj is None:
                return self.fget        if self.fget is None:
                raise AttributeError(), "unreadable attribute"
            return self.fget(obj)
    
        def __set__(self, obj, value):
            if self.fset is None:
                raise AttributeError, "can't set attribute"
            return self.fset(obj, value)
    
        def __delete__(self, obj):
            if self.fdel is None:
                raise AttributeError, "can't delete attribute"
            return self.fdel(obj)
    
        def getter(self, fget):
            return type(self)(fget, self.fset, self.fdel, self.__doc__)
    
        def setter(self, fset):
            return type(self)(self.fget, fset, self.fdel, self.__doc__)
    
        def deleter(self, fdel):
            return type(self)(self.fget, self.fset, fdel, self.__doc__)复制代码

    staticmethod 的 Python 版实现:

    class staticmethod:
    
        def __init__(self, func):
            self.func = func
    
        def __get__(self, obj, objtype=None):
            return self.func
    复制代码

    classmethod 的 Python 版实现:

    class classmethod:
    
        def __init__(self, func):
            self.func = func
    
        def __get__(self, obj, klass=None):
            if klass is None:
                klass = type(obj)
            def newfunc(*args):
                return self.func(klass, *args)
            return newfunc
    复制代码

    除此之外,你还可以实现其他功能强大的装饰器。

    由此可见,通过描述符我们可以实现强大而灵活的属性管理功能,对于一些要求属性控制比较复杂的场景,我们可以选择用描述符来实现。

    总结

    这篇文章我们主要讲了 Python 描述符的工作原理。

    首先,我们从一个简单的例子了解到,一个类属性是可以托管给另外一个类的,这个类如果实现了描述符协议方法,那么这个类属性就是一个描述符。此外,描述符又可以分为数据描述符和非数据描述符。

    之后我们又分析了获取一个属性的过程,一切的入口都在 __getattribute__ 中,这个方法定义了寻找属性的顺序,其中实例属性优先于数据描述符调用,数据描述符要优先于非数据描述符调用。

    또한 메소드가 실제로는 데이터 디스크립터가 아니라는 것도 배웠습니다. __getattribute__의 속성 검색 순서에 따라 클래스에 동일한 이름의 인스턴스 속성과 메소드를 정의하면 인스턴스 속성이 먼저 액세스됩니다. __getattribute__ 中的属性查找顺序,实例属性优先访问。

    最后我们分析了 functionmethod 的区别,以及使用 Python 描述符也可以实现 propertystaticmethodclassmethod

    마지막으로 함수메서드의 차이점을 분석하고 Python 설명자를 사용하여 속성정적 메서드를 구현했습니다. , classmethod 데코레이터.

    Python 설명자는 강력한 속성 액세스 제어 기능을 제공하며 복잡한 속성 제어가 필요한 시나리오에서 이를 사용할 수 있습니다.

    이 작품은 "CC 라이선스"를 채택하고 있으며, 재인쇄 시 작성자와 이 글의 링크를 명시해야 합니다🎜

    위 내용은 Python 설명자의 의미 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명
    이 기사는 learnku에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
    차이 이해 : 파이썬의 루프 및 루프 용차이 이해 : 파이썬의 루프 및 루프 용May 16, 2025 am 12:17 AM

    thedifferencebet weenaforloopandawhileloopinpythonisthataforloopisusured wherleationsisknortiStiskNowninAdvance, whileLeOpisUssed whileLoopisUssedStoBeCheckedThoBeCheckedTherfeTefeateThinumberofiTeRations.1) forloopsareIdealFerenceCecenceS

    Python 루프 제어 : 대 VS의 경우 - 비교Python 루프 제어 : 대 VS의 경우 - 비교May 16, 2025 am 12:16 AM

    Python에서는 반복의 수가 알려진 경우에 루프가 적합한 반면, 반복 횟수가 알려지지 않고 더 많은 제어가 필요한 경우 루프는 적합합니다. 1) 루프의 경우 간결하고 피해자 코드가있는 목록, 문자열 등과 같은 시퀀스에 적합합니다. 2) 조건에 따라 루프를 제어하거나 사용자 입력을 기다릴 때 루프가 더 적절하지만 무한 루프를 피하기 위해주의를 기울여야합니다. 3) 성능 측면에서 For 루프는 약간 빠르지 만 차이는 일반적으로 크지 않습니다. 올바른 루프 유형을 선택하면 코드의 효율성과 가독성이 향상 될 수 있습니다.

    파이썬에서 두 목록을 결합하는 방법 : 5 가지 쉬운 방법파이썬에서 두 목록을 결합하는 방법 : 5 가지 쉬운 방법May 16, 2025 am 12:16 AM

    파이썬에서 목록은 5 가지 방법을 통해 병합 될 수 있습니다. 1) 단순하고 직관적 인 연산자를 사용하여 작은 목록에 적합합니다. 2) Extend () 메소드를 사용하여 자주 업데이트 해야하는 목록에 적합한 원본 목록을 직접 수정하십시오. 3) 목록 분석 공식, 요소에 대한 간결하고 운영; 4) 효율적인 메모리에 IterTools.chain () 함수를 사용하여 대형 데이터 세트에 적합합니다. 5) * 연산자 및 Zip () 함수를 사용하여 요소를 짝을 이루어야하는 장면에 적합합니다. 각 방법에는 특정 용도 및 장점 및 단점이 있으며 선택할 때 프로젝트 요구 사항 및 성능을 고려해야합니다.

    루프 대 루프 : 파이썬 구문, 사용 사례 및 예제루프 대 루프 : 파이썬 구문, 사용 사례 및 예제May 16, 2025 am 12:14 AM

    Forloopsareusedwhendumberofiterationsisknown, whileloopsareusediltilaconditionismet.1) forloopsareIdealfecquenceslikelists, idingsyntax likes'forfruitinfruits : print (fruit) '

    Python Concatenate 목록 목록Python Concatenate 목록 목록May 16, 2025 am 12:08 AM

    Toconcatenatealistoflistsinpython, usextend, listcomprehensions, itertools.chain, orrecursiveFunctions.1) extendMethodistRaightForwardButverbose.2) ListComprehensionsArecisancisancisancisancisanceciancectionforlargerdatasets.3) itertools.chainismory-lefforforlargedas

    Python의 병합 목록 : 올바른 메소드 선택Python의 병합 목록 : 올바른 메소드 선택May 14, 2025 am 12:11 AM

    Tomergelistsinpython, youcanusethe operator, extendmethod, listcomprehension, oritertools.chain, 각각은 각각의 지위를 불러 일으킨다

    Python 3에서 두 목록을 연결하는 방법은 무엇입니까?Python 3에서 두 목록을 연결하는 방법은 무엇입니까?May 14, 2025 am 12:09 AM

    Python 3에서는 다양한 방법을 통해 두 개의 목록을 연결할 수 있습니다. 1) 작은 목록에 적합하지만 큰 목록에는 비효율적입니다. 2) 메모리 효율이 높지만 원래 목록을 수정하는 큰 목록에 적합한 확장 방법을 사용합니다. 3) 원래 목록을 수정하지 않고 여러 목록을 병합하는 데 적합한 * 운영자 사용; 4) 메모리 효율이 높은 대형 데이터 세트에 적합한 itertools.chain을 사용하십시오.

    Python은 문자열을 연결합니다Python은 문자열을 연결합니다May 14, 2025 am 12:08 AM

    join () 메소드를 사용하는 것은 Python의 목록에서 문자열을 연결하는 가장 효율적인 방법입니다. 1) join () 메소드를 사용하여 효율적이고 읽기 쉽습니다. 2)주기는 큰 목록에 비효율적으로 운영자를 사용합니다. 3) List Comprehension과 Join ()의 조합은 변환이 필요한 시나리오에 적합합니다. 4) READE () 방법은 다른 유형의 감소에 적합하지만 문자열 연결에 비효율적입니다. 완전한 문장은 끝납니다.

    See all articles

    핫 AI 도구

    Undresser.AI Undress

    Undresser.AI Undress

    사실적인 누드 사진을 만들기 위한 AI 기반 앱

    AI Clothes Remover

    AI Clothes Remover

    사진에서 옷을 제거하는 온라인 AI 도구입니다.

    Undress AI Tool

    Undress AI Tool

    무료로 이미지를 벗다

    Clothoff.io

    Clothoff.io

    AI 옷 제거제

    Video Face Swap

    Video Face Swap

    완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

    인기 기사

    Nordhold : Fusion System, 설명
    1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌
    <exp exp> 모호한 : 원정 33- 완벽한 크로마 촉매를 얻는 방법
    2 몇 주 전By尊渡假赌尊渡假赌尊渡假赌

    뜨거운 도구

    Eclipse용 SAP NetWeaver 서버 어댑터

    Eclipse용 SAP NetWeaver 서버 어댑터

    Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

    PhpStorm 맥 버전

    PhpStorm 맥 버전

    최신(2018.2.1) 전문 PHP 통합 개발 도구

    VSCode Windows 64비트 다운로드

    VSCode Windows 64비트 다운로드

    Microsoft에서 출시한 강력한 무료 IDE 편집기

    스튜디오 13.0.1 보내기

    스튜디오 13.0.1 보내기

    강력한 PHP 통합 개발 환경

    드림위버 CS6

    드림위버 CS6

    시각적 웹 개발 도구