Nice programing

`import module`이`from module import function`보다 더 나은 코딩 스타일입니까?

nicepro 2020. 11. 15. 11:43
반응형

`import module`이`from module import function`보다 더 나은 코딩 스타일입니까?


from module import functionFMIF 코딩 스타일이라고 합시다 .

import moduleIM 코딩 스타일이라고 합시다 .

from package import moduleFPIM 코딩 스타일이라고 합시다 .

IM + FPIM이 FMIF보다 더 나은 코딩 스타일로 간주되는 이유는 무엇입니까? ( 이 질문에 대한 영감을 얻으려면 이 게시물참조하십시오 .)

IM보다 FMIF를 선호하는 몇 가지 기준은 다음과 같습니다.

  1. 코드의 짧음 : 더 짧은 함수 이름을 사용할 수 있으므로 행당 80 개의 열 규칙을 고수하는 데 도움이됩니다.
  2. 가독성 : chisquare(...)보다 가독성이 좋습니다 scipy.stats.stats.chisquare(...). 이것은 주관적인 기준이지만 대부분의 사람들이 동의 할 것이라고 생각합니다.
  3. 리디렉션의 용이성 : 나는 FMIF를 사용하고 일부 나중에 어떤 이유로 정의 파이썬을 재 지정하려면 function에서 alt_module대신 module내가 한 줄을 변경해야합니다 from alt_module import function. IM을 사용하려면 여러 줄의 코드를 변경해야합니다.
FPIM이 처음 두 문제를 무효화하는 방법을 알고 있지만 세 번째 문제는 어떻습니까?

IM + FPIM이 FMIF보다 나은 모든 이유에 관심이 있지만 특히 여기에 언급 된 다음 사항에 대해 자세히 설명하고자 합니다 .

IM의 장점 :

  1. 테스트에서 조롱 / 주입의 용이성. (저는 최근에 그 용어의 의미를 배웠지 만 조롱에 익숙하지 않습니다. 여기서 IM이 FMIF보다 얼마나 나은지 보여주는 코드를 보여줄 수 있습니까?)
  2. 일부 항목을 재정 의하여 모듈을 유연하게 변경할 수있는 기능. (이것이 IM에 비해 FMIF의 장점 인 것처럼 보이므로 오해하고있는 것 같습니다. 위의 FMIF를 선호하는 세 번째 이유를 참조하십시오.)
  3. 데이터 직렬화 및 복구에 대한 예측 가능하고 제어 가능한 동작. (IM 또는 FMIF 선택이이 문제에 어떤 영향을 미치는지 잘 모르겠습니다. 자세히 설명해주세요.)
  4. 나는 FMIF가 "내 네임 스페이스를 오염시킨다"는 것을 이해하지만, 부정적으로 들리는 문구가 아니라 구체적인 방식으로 코드를 어떻게 손상시키는 지 감사하지 않습니다.
추신. 이 질문을 작성하는 동안 질문이 주관적이며 종결 될 수 있다는 경고를 받았습니다. 닫지 마세요. 나는 주관적인 의견을 찾는 것이 아니라 IM + FPIM이 FMIF보다 확실히 더 나은 구체적인 코딩 상황을 찾고 있습니다.

감사합니다.


IM / FPIM에 대해 나열한 부정은 종종 적절한 as사용으로 개선 될 수 있습니다 . from some.package import mymodulewithalongname as mymod유용하게 코드를 단축하고 가독성을 높일 수 있으며 내일로 이름 mymodulewithalongname바꾸면 somethingcompletelydifferent해당 as절을 단일 문으로 사용하여 편집 할 수 있습니다.

pro-FMIF 지점 3 (리디렉션을 위해 R이라고 함)과 pro-FPIM 지점 2 (유연성을 위해 F라고 함)를 고려하십시오. R은 모듈 경계의 무결성 손실을 촉진하는 반면 F는이를 강화합니다. 모듈의 여러 함수, 클래스 및 변수는 종종 함께 작동하도록 의도됩니다. 서로 다른 의미로 독립적으로 전환해서는 안됩니다. 예를 들어, 모듈 고려 random하고 그 기능을 seed하고 uniform: 다른 모듈에 그 중 하나의 수입을 전환 할 수 있다면, 당신은 호출 사이의 정상적인 연결을 깰 것 seed및 호출의 결과를 uniform. 모듈이 응집력과 무결성으로 잘 설계되었을 때, 모듈의 경계를 허물기위한 R의 촉진은 실제로 부정적입니다. 이는 더 나은 일을 더 쉽게 할 수있게합니다.하지 않습니다 .

반대로, F는 결합 된 함수, 클래스 및 변수 (일반적으로 함께 속한 엔티티의 모듈성에 의해)의 조정 된 전환을 가능하게 합니다 . 예를 들어, (FPIM 프로 포인트 1), 당신은 모두를 조롱 반복 테스트를 만들려면 모듈 및 코드가 FPIM을 따르는 경우에, 당신은 모든 준비, 조정 보장; 그러나 함수를 직접 가져온 코드가있는 경우 이러한 각 모듈을 찾아서 조롱을 반복해서 반복해야합니다. 테스트를 완벽하게 반복 가능하게 만들려면 일반적으로 날짜 및 시간 함수의 "조율 된 조롱" 이 필요합니다. 일부 모듈에서 사용하는 경우 모든 모듈을 찾아 조롱해야합니다.seedrandomrandomfrom datetime import datetimefrom time import time, 등) 시스템의 여러 부분이 "지금 몇시입니까?"라고 물을 때받은 모든 시간을 보장합니다. 완벽하게 일관성이 있습니다 (FPIM을 사용하는 경우 두 개의 관련 모듈을 조롱합니다).

정말 많이 추가되지 값이 사용하여 거기 때문에 FPIM처럼, 곱셈 (A 단독으로 자격을 갖춘 사람이 아니라 자격을 갖춘 이름을 barenames과 자격을 갖춘 이름 사이에 차이가있는 동안 거대한 - 당신이 얻을 그래서 자격을 갖춘 이름으로 더 많은 컨트롤을 단독으로 수 또는 번식하십시오.

아 글쎄, 당신의 모든 요점에 응답하는 데 모든 근무일을 할애 할 수는 없습니다. 당신의 질문은 아마도 6 개의 질문이어야합니다 .-). 나는 이것이 적어도 "왜 F가 R보다 나은지"와 일부 조롱 / 테스트 문제를 해결하기를 바랍니다. 이것은 잘 설계된 모듈성을 (R을 통해) 손상시키기보다는 (F를 통해) 보존하고 향상시키는 것으로 귀결됩니다 .


이것에 대한 고전적인 텍스트는 종종 effbot 인 Fredrik Lundh의 글입니다. 그의 충고 : 항상 import를 사용하십시오 .

즉, 현명해야합니다. 개인적으로 저는 여러 모듈이 깊은 것은 무엇이든 가져 오는 경향이 있다는 것을 발견했습니다 from x.y.z import a. 주된 예는 Django 모델입니다. 그러나 다른 무엇보다 스타일의 문제이며, 특히 포함 된 모듈과 datetime클래스가 동일한 것으로 불리는, 같은 모듈에서 일관성을 가져야합니다 . 당신은 쓸 필요가 있나요 datetime.datetime.now()아니면 그냥 datetime.now()? (내 코드에서는 항상 전자입니다.)

질문 목록의 항목 1과 2가 같은 문제인 것 같습니다. Python의 동적 특성은 어떤 메서드를 사용하든 모듈의 네임 스페이스에서 항목을 교체하는 것이 매우 간단하다는 것을 의미합니다. 모듈의 한 기능이 다른 기능을 참조하는 경우 어려움이 발생합니다. 이 경우 함수가 아닌 모듈을 가져 오면 수행 할 수 module.function_to_replace = myreplacementfunc있고 모든 것이 투명하게 작동하지만 IM을 사용하는 것만큼이나 FPIM을 통해 쉽게 수행 할 수 있습니다 .

나는 또한 항목 3이 어떤 것과 어떤 관련이 있는지 이해하지 못합니다. 그러나 귀하의 항목 4는 약간의 오해에 근거한 것 같습니다. 당신이 제공하는 어떤 방법도 '네임 스페이스를 오염'시키지 않을 것입니다. 무엇을 않는 것입니다 그렇게 from module import *당신이 가져 오는 것을 전혀 생각이 없다 어디, 기능은 온 독자에게 주어진 단서와 코드에 표시 할 수 있습니다. 그것은 끔찍하며 어떤 대가를 치르더라도 피해야합니다.


여기에 훌륭한 답변 (모두 찬성 투표)이 있으며이 문제에 대한 내 생각은 다음과 같습니다.

먼저 각 총알을 해결합니다.

(추론) FMIF의 장점 :

  • 짧은 코드 : 짧은 함수 이름은 한 줄에 80 개 열을 유지하는 데 도움이됩니다.

아마도 모듈 이름은 일반적으로 충분히 짧기 때문에 관련성이 없습니다. 물론, 거기 datetime뿐만 아니라 os, re, sys, 등 그리고 파이썬은 내부에 무료로 줄 바꿈이 있습니다 { [ (. 중첩 모듈의 경우 항상 asIM과 FPIM 모두에 있습니다.

  • 가독성 : chisquare (...)는 scipy.stats.stats.chisquare (...)보다 더 읽기 쉽습니다.

강하게 동의. 외래 코드 (또는 몇 달 후 내 코드)를 읽을 때 각 함수의 출처를 알기가 어렵습니다. 정규화 된 이름을 사용하면 2345 줄에서 모듈 선언 헤더로 앞뒤로 이동할 필요가 없습니다. 그리고 그것은 또한 당신에게 다음과 같은 맥락 을 제공합니다 : " chisquare? 그게 뭔데? 오, 그게 scypy뭔데? 좋아, 그럼 수학과 관련된 것들" . 다시 한 번 scipy.stats.stats as scypyst. scypyst.chisquare(...)자격을 갖춘 이름의 모든 혜택을받을 수있을만큼 짧습니다.

import os.path as osp 한 번의 호출로 3 개 이상의 함수를 연결하는 것이 매우 일반적이라는 점을 고려하면 또 다른 좋은 예입니다 : join (expanduser (), basename (splitext ())) 등.

  • 리디렉션의 용이성 : 모듈 대신 altmodule에서 함수를 한 줄로 재정의합니다.

How often you want to redefine a single function but not whole module? Module boundaries and function coordination should be preserved, and Alex already explained this in great depth. For most (all?) real-world scenarios, if alt_module.x is a viable replacement for module.x, then probably alt_module itself is a drop in alternative for module, so both IM and FPIM are one-liners just like FMIF, provided you use as.

  • I realize FPIM goes some way to nullifying the first two issues...

Actually, as is the one that mitigates the first 2 issues (and the 3rd), not FPIM. You can use IM for that too: import some.long.package.path.x as x for the same result as FPIM.


So none of the above are really pros of FMIF. And the reasons I prefer IM/FPIM are:

For the sake of simplicity and consistency, when I import something, either IM or FPIM, I'm always importing a module, not an object from a module. Remember FMIF can be (ab-)used to import functions, classes, variables, or even other modules! Think about the mess of from somemodule import sys, somevar, os, SomeClass, datetime, someFunc.

Also, if you want more than a single object from a module, FMIF will pollute your namespace more than IM or FPIM, which will use a single name no matter how many objects you want to use. And such objects will have a qualified name, which is a pro, not a con: as I've said in issue 2, IMHO a it improves readability.

it all comes down to consistency, simplicity, organization. "Import modules, not objects" is a good, easy mind model to stick with.


Like Alex Martelli, I am fond of using as when importing a function.

One thing I have done is to use some prefix on all the functions that were imported from the same module:

from random import seed as r_seed
from random import random as r_random

r_seed is shorter to type than random.seed but somewhat preserves the module boundaries. Someone casually looking at your code can see r_seed() and r_random() and have a chance to grok that they are related.

Of course, you can always simply do:

import random as r

and then use r.random() and r.seed(), which may be the ideal compromise for this case. I only use the prefix trick when I'm importing one or two functions from a module. When I want to use many functions from the same module, I'll import the module, perhaps with an as to shorten the name.


I agree with MestreLion the most here (and so an upvote).

My perspective: I review code frequently that I am unfamiliar with, and not knowing what module a function is coming from just looking at the function is quite frustrating.

Code is written once and read many times, and so readability and maintainability trumps ease of typing.

In a similar vein, typically code is not being written for the benefit of the coder, but for the benefit of another entity.

Your code should be readable to someone who knows python better than you, but is unfamiliar with the code.

Full path imports can also better help IDE's point you at the correct source of the function or object you're looking at.

For all of these reasons and the reasons MestreLion noted, I conclude that it is best practice to import and use the full path.

참고URL : https://stackoverflow.com/questions/1744258/is-import-module-better-coding-style-than-from-module-import-function

반응형