최근 Python을 사용하는 과정에서 변수 객체 datetime.datetime.now()를 함수의 기본 매개변수로 사용하는 경우, 모듈 순환 종속성 등 몇 가지 함정에 직면했습니다.
향후 문의 및 추가를 위해 여기에 기록해 주세요.
변경 가능한 객체를 기본 매개변수로 사용하지 마세요
함수를 사용할 때 기본 매개변수가 포함되는 경우가 많습니다. Python에서 변경 가능한 객체를 기본 매개변수로 사용하면 예기치 않은 결과가 발생할 수 있습니다.
아래 예를 보세요.
def append_item(a = 1, b = []): b.append(a) print b append_item(a=1) append_item(a=3) append_item(a=5)
결과는 다음과 같습니다.
[1] [1, 3] [1, 3, 5]
결과에서 볼 수 있듯이 나중에append_item 함수를 두 번 호출하면 , 함수 매개변수 b는 []로 초기화되지 않지만 이전 함수 호출의 값을 유지합니다.
이러한 결과가 나오는 이유는 Python에서는 함수 정의 시 함수 매개변수의 기본값이 한 번만 초기화되기 때문입니다.
Python의 이 기능을 증명하는 예를 살펴보겠습니다.
class Test(object): def __init__(self): print("Init Test") def arg_init(a, b = Test()): print(a) arg_init(1) arg_init(3) arg_init(5)
결과는 다음과 같습니다.
Init Test 1 3 5
이 예의 결과에서 볼 수 있듯이 , Test 클래스만 한 번 인스턴스화됩니다. 즉, 기본 매개변수는 함수 호출 횟수와 관련이 없으며 함수가 정의될 때 한 번만 초기화됩니다.
가변 기본 매개변수의 올바른 사용
가변 기본 매개변수의 경우 다음 패턴을 사용하여 위와 같은 예상치 못한 결과를 방지할 수 있습니다.
def append_item(a = 1, b = None): if b is None: b = [] b.append(a) print b append_item(a=1) append_item(a=3) append_item(a=5)
결과는 다음과 같습니다.
[1] [3] [5]
Python의 범위
Python의 범위 확인 순서는 Local, Enclosing, Global, 내장입니다. 즉, Python 인터프리터가 변수를 이 순서로 구문 분석합니다.
간단한 예를 살펴보세요.
global_var = 0 def outer_func(): outer_var = 1 def inner_func(): inner_var = 2 print "global_var is :", global_var print "outer_var is :", outer_var print "inner_var is :", inner_var inner_func() outer_func()
결과는 다음과 같습니다.
global_var is : 0 outer_var is : 1 inner_var is : 2
Python에서 범위에 관해 주의할 점 중 하나는 범위의 변수에 값을 할당할 때 Python이 해당 변수를 현재 범위의 지역 변수로 간주한다는 것입니다.
이 역시 비교적 이해하기 쉽습니다. 다음 코드의 경우 var_func는 num 변수에 값을 할당하므로 여기서 num은 var_func 범위의 로컬 변수입니다.
num = 0 def var_func(): num = 1 print "num is :", num var_func()
문제 1
그런데, 변수를 아래와 같이 사용하면 문제가 발생합니다.
num = 0 def var_func(): print "num is :", num num = 1 var_func()
결과는 다음과 같습니다.
UnboundLocalError: local variable 'num' referenced before assignment
이 오류가 발생하는 이유는 var_func의 num 변수에 값을 할당했기 때문에 Python 인터프리터는 num이 var_func 범위의 지역 변수라고 생각하지만 코드를 실행하여 인쇄하면 "num is :", num 문을 실행할 때 num은 여전히 정의되지 않습니다.
질문 2
위 오류는 비교적 명백하며, 다음과 같이 좀 더 미묘한 오류 형태도 있습니다.
li = [1, 2, 3] def foo(): li.append(4) print li foo() def bar(): li +=[5] print li bar()
코드 결과는 다음과 같습니다.
[1, 2, 3, 4] UnboundLocalError: local variable 'li' referenced before assignment
foo 함수에서는 Python의 범위 구문 분석 순서에 따라 이 함수에서는 전역 li 변수가 사용되지만 bar 함수에서는 li 변수가 할당됩니다. 따라서 li는 bar 범위에서 변수로 처리됩니다.
bar 함수의 이 문제에는 전역 키워드를 사용할 수 있습니다.
li = [1, 2, 3] def foo(): li.append(4) print li foo() def bar(): global li li +=[5] print li bar()
클래스 속성은 숨겨져 있습니다
파이썬에는 클래스 속성과 인스턴스 속성이 있습니다. 클래스 속성은 클래스 자체에 속하며 모든 클래스 인스턴스에서 공유됩니다.
클래스 속성은 클래스 이름을 통해 액세스 및 수정이 가능하며, 클래스 인스턴스를 통해서도 액세스 및 수정이 가능합니다. 그러나 인스턴스가 클래스와 동일한 이름의 속성을 정의하면 클래스 속성이 숨겨집니다.
다음 예를 보세요.
class Student(object): books = ["Python", "JavaScript", "CSS"] def __init__(self, name, age): self.name = name self.age = age pass wilber = Student("Wilber", 27) print "%s is %d years old" %(wilber.name, wilber.age) print Student.books print wilber.books wilber.books = ["HTML", "AngularJS"] print Student.books print wilber.books del wilber.books print Student.books print wilber.books
코드의 결과는 다음과 같습니다. 처음에는 Wilber 인스턴스에서 책에 직접 액세스할 수 있습니다. 하지만 Wilber 인스턴스가 정의된 경우 books라는 인스턴스 속성을 삭제한 후 Wilber 인스턴스의 books 속성은 Wilber 인스턴스의 books 속성인 wilber.books를 삭제한 후 클래스의 books 속성을 "숨깁니다". 다시 클래스의 books 속성에 해당합니다.
Wilber is 27 years old ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS'] ['HTML', 'AngularJS'] ['Python', 'JavaScript', 'CSS'] ['Python', 'JavaScript', 'CSS']
파이썬 값에서 상속을 사용할 때는 클래스 속성이 숨겨지는 것도 주의해야 합니다. 클래스의 경우 클래스의 __dict__ 속성을 통해 모든 클래스 속성을 볼 수 있습니다.
当通过类名来访问一个类属性的时候,会首先查找类的__dict__属性,如果没有找到类属性,就会继续查找父类。但是,如果子类定义了跟父类同名的类属性后,子类的类属性就会隐藏父类的类属性。
看一个例子:
class A(object): count = 1 class B(A): pass class C(A): pass print A.count, B.count, C.count B.count = 2 print A.count, B.count, C.count A.count = 3 print A.count, B.count, C.count print B.__dict__ print C.__dict__
结果如下,当类B定义了count这个类属性之后,就会隐藏父类的count属性:
1 1 1 1 2 1 3 2 3 {'count': 2, '__module__': '__main__', '__doc__': None} {'__module__': '__main__', '__doc__': None}
tuple是“可变的”
在Python中,tuple是不可变对象,但是这里的不可变指的是tuple这个容器总的元素不可变(确切的说是元素的id),但是元素的值是可以改变的。
tpl = (1, 2, 3, [4, 5, 6]) print id(tpl) print id(tpl[3]) tpl[3].extend([7, 8]) print tpl print id(tpl) print id(tpl[3])
代码结果如下,对于tpl对象,它的每个元素都是不可变的,但是tpl[3]是一个list对象。也就是说,对于这个tpl对象,id(tpl[3])是不可变的,但是tpl[3]确是可变的。
36764576 38639896 (1, 2, 3, [4, 5, 6, 7, 8]) 36764576 38639896
Python的深浅拷贝
在对Python对象进行赋值的操作中,一定要注意对象的深浅拷贝,一不小心就可能踩坑了。
当使用下面的操作的时候,会产生浅拷贝的效果:
使用切片[:]操作
使用工厂函数(如list/dir/set)
使用copy模块中的copy()函数
使用copy模块里面的浅拷贝函数copy():
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.copy(will) print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber] will[0] = "Wilber" will[2].append("CSS") print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber]
使用copy模块里面的深拷贝函数deepcopy():
import copy will = ["Will", 28, ["Python", "C#", "JavaScript"]] wilber = copy.deepcopy(will) print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber] will[0] = "Wilber" will[2].append("CSS") print id(will) print will print [id(ele) for ele in will] print id(wilber) print wilber print [id(ele) for ele in wilber]
模块循环依赖
在Python中使用import导入模块的时候,有的时候会产生模块循环依赖,例如下面的例子,module_x模块和module_y模块相互依赖,运行module_y.py的时候就会产生错误。
# module_x.py import module_y def inc_count(): module_y.count += 1 print module_y.count # module_y.py import module_x count = 10 def run(): module_x.inc_count() run()
其实,在编码的过程中就应当避免循环依赖的情况,或者代码重构的过程中消除循环依赖。
当然,上面的问题也是可以解决的,常用的解决办法就是把引用关系搞清楚,让某个模块在真正需要的时候再导入(一般放到函数里面)。
对于上面的例子,就可以把module_x.py修改为如下形式,在函数内部导入module_y:
# module_x.py def inc_count(): import module_y module_y.count += 1

PythonlistsCanstoreAnyDatAtype, ArrayModuLearRaysStoreOneType 및 NUMPYARRAYSAREFORNUMERICALPUTATION.1) LISTSAREVERSATILEBUTLESSMEMORY-EFFICENT.2) ARRAYMODUERRAYRAYRAYSARRYSARESARESARESARESARESARESAREDOREDORY-UNFICEDONOUNEOUSDATA.3) NumpyArraysUraysOrcepperperperperperperperperperperperperperperperferperferperferferpercient

whenyouattempttoreavalueofthewrongdatatypeinapythonaphonarray, thisiSdueTotheArrayModule의 stricttyPeenforcement, theAllElementStobeofthesAmetypecified bythetypecode.forperformancersassion, arraysaremoreficats the thraysaremoreficats thetheperfication the thraysaremorefications는

Pythonlistsarepartoftsandardlardlibrary, whileraysarenot.listsarebuilt-in, 다재다능하고, 수집 할 수있는 반면, arraysarreprovidedByTearRaymoduledlesscommonlyusedDuetolimitedFunctionality.

thescriptIsrunningwithHongpyThonversionDueCorRectDefaultTerpretersEttings.tofixThis : 1) checktheDefaultPyThonVersionUsingPyThon-VersionorPyThon3- version.2) usvirtual-ErondmentsBythePython.9-Mvenvmyenv, 활성화, 및 파괴

PythonArraysSupportVariousOperations : 1) SlicingExtractsSubsets, 2) 추가/확장 어드먼트, 3) 삽입 값 삽입 ATSpecificPositions, 4) retingdeletesElements, 5) 분류/ReversingChangesOrder 및 6) ListsompectionScreateNewListSbasedOnsistin

NumpyArraysareSentialplosplicationSefficationSefficientNumericalcomputationsanddatamanipulation. Theyarcrucialindatascience, MachineLearning, Physics, Engineering 및 Financeduetotheiribility에 대한 handlarge-scaledataefficivally. forexample, Infinancialanyaly

UseanArray.ArrayOveralistInpyThonWhendealingwithhomogeneousData, Performance-CriticalCode, OrinterFacingwithCcode.1) HomogeneousData : ArraysSaveMemorywithtypepletement.2) Performance-CriticalCode : arraysofferbetterporcomanceFornumericalOperations.3) Interf

아니요, NOTALLLISTOPERATIONARESUPPORTEDBYARRARES, andVICEVERSA.1) ArraySDONOTSUPPORTDYNAMICOPERATIONSLIKEPENDORINSERTWITHUTRESIGING, WHITHIMPACTSPERFORMANCE.2) ListSDONOTEECONSTANTTIMECOMPLEXITEFORDITITICCESSLIKEARRAYSDO.


핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

mPDF
mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

드림위버 CS6
시각적 웹 개발 도구

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.
