Guest User

Untitled

a guest
Jun 21st, 2018
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.54 KB | None | 0 0
  1. 1. 다음 special method들의 기능을 확인하세요
  2.  
  3. object.__call__(self[, args...]) - 생성된 인스턴스를 함수 처럼 호출 가능하게 해준다.
  4. 클래스 내에서 이 메서드가 정의되면,
  5. 인스턴스 x 는 x(arg1, arg2, ...) 와 같이 함수 형태로 호출이 가능하다.
  6. x(arg1, arg2, ...) 는 x.__call__(arg1, arg2, ...) 의 줄인 표현이다.
  7.  
  8. class Factorial:
  9. def __init__(self):
  10. self.cache = {}
  11.  
  12. def __call__(self, n):
  13. if n not in self.cache:
  14. if n == 0:
  15. self.cache[n] = 1
  16. else:
  17. self.cache[n] = n * self.__call__(n - 1)
  18. return self.cache[n]
  19.  
  20. fact = Factorial()
  21.  
  22. for i in range(10):
  23. print ('%d! = %d' % (i, fact(i)))
  24.  
  25.  
  26.  
  27. object.__len__(self) - 생성된 인스턴스를 내장함수 len() 에 사용할수 있도록 해준다.
  28. 이 메서드를 정의하지 않고 len(x) 처럼 사용하면 TypeError: object of type 'Factorial' has no len() 와 같은 에러를 낸다.
  29.  
  30. class Factorial:
  31. def __init__(self):
  32. self.cache = {}
  33.  
  34. def __call__(self, n):
  35. if n not in self.cache:
  36. if n == 0:
  37. self.cache[n] = 1
  38. else:
  39. self.cache[n] = n * self.__call__(n - 1)
  40. return self.cache[n]
  41. def __len__(self):
  42. return len(self.cache)
  43.  
  44. fact = Factorial()
  45.  
  46. for i in range(10):
  47. print ('%d! = %d' % (i, fact(i)))
  48.  
  49. print(len(fact))
  50.  
  51.  
  52.  
  53. object.__contains__(self, item) - 멤버십 검사 연산자를 구현하기 위해 호출된다. (in 또는 not in)
  54. item 이 self 에 있으면 참을, 그렇지 않으면 거짓을 돌려줘야 한다.
  55. 매핑 객체의 경우, 키-값 쌍이 아니라 매핑의 키가 고려되어야 한다.
  56.  
  57. class Factorial:
  58. def __init__(self):
  59. self.cache = {}
  60.  
  61. def __call__(self, n):
  62. if n not in self.cache:
  63. if n == 0:
  64. self.cache[n] = 1
  65. else:
  66. self.cache[n] = n * self.__call__(n - 1)
  67. return self.cache[n]
  68. def __len__(self):
  69. return len(self.cache)
  70. def __contains__(self, item):
  71. if item in self.cache.keys():
  72. return True
  73. else:
  74. return False
  75.  
  76. fact = Factorial()
  77.  
  78. for i in range(10):
  79. print ('%d! = %d' % (i, fact(i)))
  80.  
  81. print(9 in fact)
  82. print(11 in fact)
  83.  
  84.  
  85.  
  86. object.__getitem__(self, key) - self[key] 의 값을 구하기 위해 호출된다.
  87. 시퀸스형이나 매핑형 객체들 처럼 객체[키] 형태로 사용한다.
  88.  
  89. class Factorial:
  90. def __init__(self):
  91. self.cache = {}
  92.  
  93. def __call__(self, n):
  94. if n not in self.cache:
  95. if n == 0:
  96. self.cache[n] = 1
  97. else:
  98. self.cache[n] = n * self.__call__(n - 1)
  99. return self.cache[n]
  100. def __len__(self):
  101. return len(self.cache)
  102. def __contains__(self, item):
  103. if item in self.cache.keys():
  104. return True
  105. else:
  106. return False
  107. def __getitem__(self, key):
  108. return self.cache[key]
  109.  
  110. fact = Factorial()
  111.  
  112. for i in range(10):
  113. print ('%d! = %d' % (i, fact(i)))
  114.  
  115. print(fact[3])
  116.  
  117.  
  118.  
  119. object.__setitem__(self, key, value) - self[key] 로의 대입을 구현하기 위해 호출된다.
  120.  
  121. class Factorial:
  122. def __init__(self):
  123. self.cache = {}
  124.  
  125. def __call__(self, n):
  126. if n not in self.cache:
  127. if n == 0:
  128. self.cache[n] = 1
  129. else:
  130. self.cache[n] = n * self.__call__(n - 1)
  131. return self.cache[n]
  132.  
  133. def __len__(self):
  134. return len(self.cache)
  135.  
  136. def __contains__(self, item):
  137. if item in self.cache.keys():
  138. return True
  139. else:
  140. return False
  141.  
  142. def __getitem__(self, key):
  143. return self.cache[key]
  144.  
  145. def __setitem__(self, key, value):
  146. self.cache[key] = value
  147.  
  148. fact = Factorial()
  149.  
  150. for i in range(10):
  151. print ('%d! = %d' % (i, fact(i)))
  152.  
  153. fact[11] = 256
  154. print(fact[11])
  155.  
  156.  
  157.  
  158. object.__delitem__(self, key) - self[key] 의 삭제를 구현하기 위해 호출된다.
  159.  
  160. class Factorial:
  161. def __init__(self):
  162. self.cache = {}
  163.  
  164. def __call__(self, n):
  165. if n not in self.cache:
  166. if n == 0:
  167. self.cache[n] = 1
  168. else:
  169. self.cache[n] = n * self.__call__(n - 1)
  170. return self.cache[n]
  171.  
  172. def __len__(self):
  173. return len(self.cache)
  174.  
  175. def __contains__(self, item):
  176. if item in self.cache.keys():
  177. return True
  178. else:
  179. return False
  180.  
  181. def __getitem__(self, key):
  182. return self.cache[key]
  183.  
  184. def __setitem__(self, key, value):
  185. self.cache[key] = value
  186.  
  187. def __delitem__(self, key):
  188. del self.cache[key]
  189.  
  190. def print_cache(self):
  191. print(self.cache)
  192.  
  193. fact = Factorial()
  194.  
  195. for i in range(10):
  196. fact(i)
  197.  
  198. fact.print_cache()
  199.  
  200. del fact[3]
  201.  
  202. fact.print_cache()
  203.  
  204.  
  205.  
  206. object.__add__(self, other) - 같은 클래스로 생성된 인스턴스 끼리 덧셈이 가능하도록 한다.
  207.  
  208. class Factorial:
  209. def __init__(self):
  210. self.cache = {}
  211.  
  212. def __call__(self, n):
  213. if n not in self.cache:
  214. if n == 0:
  215. self.cache[n] = 1
  216. else:
  217. self.cache[n] = n * self.__call__(n - 1)
  218. return self.cache[n]
  219.  
  220. def __len__(self):
  221. return len(self.cache)
  222.  
  223. def __contains__(self, item):
  224. if item in self.cache.keys():
  225. return True
  226. else:
  227. return False
  228.  
  229. def __getitem__(self, key):
  230. return self.cache[key]
  231.  
  232. def __setitem__(self, key, value):
  233. self.cache[key] = value
  234.  
  235. def __delitem__(self, key):
  236. del self.cache[key]
  237.  
  238. def __add__(self, other):
  239. return {**self.cache, **other.cache}
  240.  
  241. def print_cache(self):
  242. print(self.cache)
  243.  
  244. fact = Factorial()
  245.  
  246. for i in range(10):
  247. fact(i)
  248.  
  249. fact.print_cache()
  250.  
  251. fact2 = Factorial()
  252.  
  253. for i in range(5, 15):
  254. fact2(i)
  255.  
  256. del(fact2[0])
  257. del(fact2[1])
  258. del(fact2[2])
  259. del(fact2[3])
  260. del(fact2[4])
  261. del(fact2[5])
  262. del(fact2[6])
  263. fact2.print_cache()
  264.  
  265. print(fact + fact2)
  266.  
  267.  
  268.  
  269. object.__sub__(self, other) - 같은 클래스로 생성된 인스턴스 끼리 뺄셈이 가능하도록 한다.
  270.  
  271. class Factorial:
  272. def __init__(self):
  273. self.cache = {}
  274.  
  275. def __call__(self, n):
  276. if n not in self.cache:
  277. if n == 0:
  278. self.cache[n] = 1
  279. else:
  280. self.cache[n] = n * self.__call__(n - 1)
  281. return self.cache[n]
  282.  
  283. def __len__(self):
  284. return len(self.cache)
  285.  
  286. def __contains__(self, item):
  287. if item in self.cache.keys():
  288. return True
  289. else:
  290. return False
  291.  
  292. def __getitem__(self, key):
  293. return self.cache[key]
  294.  
  295. def __setitem__(self, key, value):
  296. self.cache[key] = value
  297.  
  298. def __delitem__(self, key):
  299. del self.cache[key]
  300.  
  301. def __add__(self, other):
  302. return {**self.cache, **other.cache}
  303.  
  304. def __sub__(self, other):
  305. x = self.cache.copy()
  306. other_keys = other.cache.keys()
  307. for key in self.cache.keys():
  308. if key in other_keys:
  309. del x[key]
  310. return x
  311.  
  312. def print_cache(self):
  313. print(self.cache)
  314.  
  315. fact = Factorial()
  316.  
  317. for i in range(10):
  318. fact(i)
  319.  
  320. fact.print_cache()
  321.  
  322. fact2 = Factorial()
  323.  
  324. for i in range(5, 15):
  325. fact2(i)
  326.  
  327. del(fact2[0])
  328. del(fact2[1])
  329. del(fact2[2])
  330. del(fact2[3])
  331. del(fact2[4])
  332. del(fact2[5])
  333. del(fact2[6])
  334. fact2.print_cache()
  335.  
  336. print(fact - fact2)
  337.  
  338.  
  339.  
  340. object.__mul__(self, other) - 같은 클래스로 생성된 인스턴스 끼리 곱셈이 가능하도록 한다.
  341.  
  342. class Factorial:
  343. def __init__(self):
  344. self.cache = {}
  345.  
  346. def __call__(self, n):
  347. if n not in self.cache:
  348. if n == 0:
  349. self.cache[n] = 1
  350. else:
  351. self.cache[n] = n * self.__call__(n - 1)
  352. return self.cache[n]
  353.  
  354. def __len__(self):
  355. return len(self.cache)
  356.  
  357. def __contains__(self, item):
  358. if item in self.cache.keys():
  359. return True
  360. else:
  361. return False
  362.  
  363. def __getitem__(self, key):
  364. return self.cache[key]
  365.  
  366. def __setitem__(self, key, value):
  367. self.cache[key] = value
  368.  
  369. def __delitem__(self, key):
  370. del self.cache[key]
  371.  
  372. def __add__(self, other):
  373. return {**self.cache, **other.cache}
  374.  
  375. def __sub__(self, other):
  376. x = self.cache.copy()
  377. other_keys = other.cache.keys()
  378. for key in self.cache.keys():
  379. if key in other_keys:
  380. del x[key]
  381. return x
  382.  
  383. def __mul__(self, other):
  384. x = {}
  385. all = self.__add__(other)
  386. self_keys = self.cache.keys()
  387. other_keys = other.cache.keys()
  388. for key in all.keys():
  389. if key in self_keys and key in other_keys:
  390. x[key] = self.cache[key] * other.cache[key]
  391. else:
  392. x[key] = 0
  393. return x
  394.  
  395. def print_cache(self):
  396. print(self.cache)
  397.  
  398. fact = Factorial()
  399.  
  400. for i in range(10):
  401. fact(i)
  402.  
  403. fact.print_cache()
  404.  
  405. fact2 = Factorial()
  406.  
  407. for i in range(5, 15):
  408. fact2(i)
  409.  
  410. del(fact2[0])
  411. del(fact2[1])
  412. del(fact2[2])
  413. del(fact2[3])
  414. del(fact2[4])
  415. del(fact2[5])
  416. del(fact2[6])
  417. fact2.print_cache()
  418.  
  419. print(fact * fact2)
  420.  
  421.  
  422.  
  423. object.__truediv__(self, other) - 같은 클래스로 생성된 인스턴스 끼리 나눗셈이 가능하도록 한다.
  424.  
  425. class Factorial:
  426. def __init__(self):
  427. self.cache = {}
  428.  
  429. def __call__(self, n):
  430. if n not in self.cache:
  431. if n == 0:
  432. self.cache[n] = 1
  433. else:
  434. self.cache[n] = n * self.__call__(n - 1)
  435. return self.cache[n]
  436.  
  437. def __len__(self):
  438. return len(self.cache)
  439.  
  440. def __contains__(self, item):
  441. if item in self.cache.keys():
  442. return True
  443. else:
  444. return False
  445.  
  446. def __getitem__(self, key):
  447. return self.cache[key]
  448.  
  449. def __setitem__(self, key, value):
  450. self.cache[key] = value
  451.  
  452. def __delitem__(self, key):
  453. del self.cache[key]
  454.  
  455. def __add__(self, other):
  456. return {**self.cache, **other.cache}
  457.  
  458. def __sub__(self, other):
  459. x = self.cache.copy()
  460. other_keys = other.cache.keys()
  461. for key in self.cache.keys():
  462. if key in other_keys:
  463. del x[key]
  464. return x
  465.  
  466. def __mul__(self, other):
  467. x = {}
  468. all = self.__add__(other)
  469. self_keys = self.cache.keys()
  470. other_keys = other.cache.keys()
  471. for key in all.keys():
  472. if key in self_keys and key in other_keys:
  473. x[key] = self.cache[key] * other.cache[key]
  474. else:
  475. x[key] = 0
  476. return x
  477.  
  478. def __truediv__(self, other):
  479. x = {}
  480. all = self.__add__(other)
  481. self_keys = self.cache.keys()
  482. other_keys = other.cache.keys()
  483. for key in all.keys():
  484. if key in self_keys and key in other_keys:
  485. if other.cache[key]:
  486. x[key] = self.cache[key] / other.cache[key]
  487. else:
  488. x[key] = None
  489. else:
  490. x[key] = None
  491. return x
  492.  
  493. def print_cache(self):
  494. print(self.cache)
  495.  
  496. fact = Factorial()
  497.  
  498. for i in range(10):
  499. fact(i)
  500.  
  501. fact.print_cache()
  502.  
  503. fact2 = Factorial()
  504.  
  505. for i in range(5, 15):
  506. fact2(i)
  507.  
  508. del(fact2[0])
  509. del(fact2[1])
  510. del(fact2[2])
  511. del(fact2[3])
  512. del(fact2[4])
  513. del(fact2[5])
  514. del(fact2[6])
  515. fact2.print_cache()
  516.  
  517. print(fact / fact2)
  518.  
  519.  
  520.  
  521. object.__lt__(self, other)
  522. object.__le__(self, other)
  523. object.__eq__(self, other)
  524. object.__ne__(self, other)
  525. object.__gt__(self, other)
  526. object.__ge__(self, other)
  527. 이것들은 소위 "풍부한 비교(rich comparison)" 메서드다.
  528. 연산자 기호와 메서드 이름 간의 관계는 다음과 같다:
  529. x<y 는 x.__lt__(y) 를 호출한다,
  530. x<=y 는 x.__le__(y) 를 호출한다,
  531. x==y 는 x.__eq__(y) 를 호출한다,
  532. x!=y 는 x.__ne__(y) 를 호출한다,
  533. x>y 는 x.__gt__(y) 를 호출한다,
  534. x>=y 는 x.__ge__(y) 를 호출한다.
  535.  
  536. class Factorial:
  537. def __init__(self):
  538. self.cache = {}
  539.  
  540. def __call__(self, n):
  541. if n not in self.cache:
  542. if n == 0:
  543. self.cache[n] = 1
  544. else:
  545. self.cache[n] = n * self.__call__(n - 1)
  546. return self.cache[n]
  547.  
  548. def __len__(self):
  549. return len(self.cache)
  550.  
  551. def __contains__(self, item):
  552. if item in self.cache.keys():
  553. return True
  554. else:
  555. return False
  556.  
  557. def __getitem__(self, key):
  558. return self.cache[key]
  559.  
  560. def __setitem__(self, key, value):
  561. self.cache[key] = value
  562.  
  563. def __delitem__(self, key):
  564. del self.cache[key]
  565.  
  566. def __add__(self, other):
  567. return {**self.cache, **other.cache}
  568.  
  569. def __sub__(self, other):
  570. x = self.cache.copy()
  571. other_keys = other.cache.keys()
  572. for key in self.cache.keys():
  573. if key in other_keys:
  574. del x[key]
  575. return x
  576.  
  577. def __mul__(self, other):
  578. x = {}
  579. all = self.__add__(other)
  580. self_keys = self.cache.keys()
  581. other_keys = other.cache.keys()
  582. for key in all.keys():
  583. if key in self_keys and key in other_keys:
  584. x[key] = self.cache[key] * other.cache[key]
  585. else:
  586. x[key] = 0
  587. return x
  588.  
  589. def __truediv__(self, other):
  590. x = {}
  591. all = self.__add__(other)
  592. self_keys = self.cache.keys()
  593. other_keys = other.cache.keys()
  594. for key in all.keys():
  595. if key in self_keys and key in other_keys:
  596. if other.cache[key]:
  597. x[key] = self.cache[key] / other.cache[key]
  598. else:
  599. x[key] = None
  600. else:
  601. x[key] = None
  602. return x
  603.  
  604. def __lt__(self, other): # self < other
  605. return sum(self.cache.values()) < sum(other.cache.values())
  606.  
  607. def __le__(self, other): # self <= other
  608. return sum(self.cache.values()) <= sum(other.cache.values())
  609.  
  610. def __eq__(self, other): # self == other
  611. return sum(self.cache.values()) == sum(other.cache.values())
  612.  
  613. def __ne__(self, other): # self != other
  614. return sum(self.cache.values()) != sum(other.cache.values())
  615.  
  616. def __gt__(self, other): # self > other
  617. return sum(self.cache.values()) > sum(other.cache.values())
  618.  
  619. def __ge__(self, other): # self >= other
  620. return sum(self.cache.values()) >= sum(other.cache.values())
  621.  
  622.  
  623. def print_cache(self):
  624. print(self.cache)
  625.  
  626. fact = Factorial()
  627.  
  628. for i in range(10):
  629. fact(i)
  630.  
  631. fact.print_cache()
  632.  
  633. fact2 = Factorial()
  634.  
  635. for i in range(5, 15):
  636. fact2(i)
  637.  
  638. del(fact2[0])
  639. del(fact2[1])
  640. del(fact2[2])
  641. del(fact2[3])
  642. del(fact2[4])
  643. del(fact2[5])
  644. del(fact2[6])
  645. fact2.print_cache()
  646.  
  647. print(fact < fact2)
  648. print(fact <= fact2)
  649. print(fact == fact2)
  650. print(fact != fact2)
  651. print(fact > fact2)
  652. print(fact >= fact2)
  653.  
  654.  
  655.  
  656. 2. Account Class 업그레이드
  657.  
  658. 수업에서 활용한 account class에 다음 기능을 추가하세요
  659. 1. 계좌 생성시에 password 지정 및 은행이름 입력.
  660. 2. 송금시에 password 입력 및 일치하는지 확인
  661. 3. 송금시에 같은 은행이 아닌 경우에는 수수로 -500 원 별도 부여
  662. 4. 소유자가 같은 계좌는 + 연산자로 보유금액 합산가능
  663. 5. 소유자가 같은지 == 연산자 혹은 != 연산자로 확인가능
  664.  
  665. class Wallet:
  666. # object.__init__(self[, ...])
  667. # (__new__() 에 의해) 인스턴스가 만들어진 후에, 하지만 호출자에게 돌려주기 전에 호출된다.
  668. # 인자들은 클래스 생성자 표현으로 전달된 것들이다. 만약 베이스 클래스가 __init__() 메서드를 갖고 있다면,
  669. # 서브 클래스의 __init__() 메서드는, 있다면, 인스턴스에서 베이스 클래스가 차지하는 부분이 올바르게 초기화됨을 확실히 하기 위해 명시적으로 호출해주어야 한다;
  670. # 예를 들어: super().__init__([args...]).
  671. def __init__(self, name):
  672. self.money = 0
  673. self.owner = name
  674. print(f"{name}님 환영합니다.[__init__]")
  675.  
  676. # object.__str__(self)
  677. # str(object) 와 내장 함수 format(), print() 에 의해 호출되어 객체의 "비형식적인(informal)" 또는 보기 좋게 인쇄 가능한 문자열 표현을 계산한다.
  678. # 반환 값은 반드시 문자열 객체여야 한다.
  679. def __str__(self):
  680. return f'{self.owner}님의 지갑입니다.[__str__]'
  681.  
  682. # object.__repr__(self)
  683. # repr() 내장 함수에 의해 호출되어 객체의 "형식적인(official)" 문자열 표현을 계산한다.
  684. # 만약 가능하다면, 이것은 같은 (적절한 환경이 주어질 때) 값을 갖는 객체를 새로 만들 수 있는 올바른 파이썬 표현식처럼 보여야 한다.
  685. # 가능하지 않다면, <...쓸모있는 설명...> 형태의 문자열을 돌려줘야 한다. 반환 값은 반드시 문자열이어야 한다.
  686. # 만약 클래스가 __str__() 없이 __repr__() 만 정의한다면, __repr__() 은 그 클래스 인스턴스의 "비형식적인(informal)" 문자열 표현이 요구될 때 사용될 수 있다.
  687. def __repr__(self):
  688. return f'{self.owner}님의 지갑입니다.[__repr__]'
  689.  
  690. def print_owner_name(self):
  691. print("owner name is", self.owner)
  692.  
  693. def print_now_money(self):
  694. print(f"현재 잔액은 {self.money}원 입니다.")
  695.  
  696. def spend(self, m):
  697. if self.money < m:
  698. print("돈이 부족합니다.")
  699. self.print_now_money()
  700. else:
  701. self.money -= m
  702. print(f"{m}원을 지출했습니다.")
  703. self.print_now_money()
  704.  
  705. def income(self, m):
  706. self.money += m
  707. self.print_now_money()
  708.  
  709. class Account(Wallet):
  710. def __init__(self, name, account_number, password, bankname):
  711. super().__init__(name)
  712. self.account_number = account_number
  713. self.password = password
  714. self.bankname = bankname
  715. print(f"{name}님 계좌정보입니다. 은행: {bankname}, 계좌번호: {account_number}, 비밀번호: {password} [__init__]")
  716.  
  717. def __add__(self, another):
  718. if self.owner == another.owner:
  719. return self.money + another.money
  720. else:
  721. return "각 계좌의 소유자가 달라서 잔액을 합산할수 없습니다."
  722.  
  723. def send_money(self, money, password, to):
  724. if self.money >= money and self.password == password:
  725. if to.bankname == self.bankname:
  726. to.money += money
  727. self.money -= money
  728. print(f"{money}원을 {to.owner}에게 보냈습니다.")
  729. self.print_now_money()
  730. else:
  731. if self.money >= money + 500:
  732. to.money += money
  733. self.money -= money + 500
  734. print(f"{money}원을 {to.bankname} {to.owner}에게 보냈습니다. 수수료는 500원 입니다.")
  735. self.print_now_money()
  736. else:
  737. print("돈이 부족합니다.")
  738. elif self.password == password:
  739. print("돈이 부족합니다.")
  740. else:
  741. print("비밀번호가 잘못 되었습니다.")
  742.  
  743.  
  744. # my_wallet = Wallet('유창화')
  745. # print(str(my_wallet))
  746. # print(repr(my_wallet))
  747. # my_wallet.income(100000)
  748. # my_wallet.spend(5000000)
  749. # my_wallet.spend(50000)
  750.  
  751. # my_account = Account('유창화', '123-12345', '12345', '국민')
  752. # print(str(my_account))
  753. # print(repr(my_account))
  754.  
  755. my_account = Account('유창화', '123-12345', '12345', '국민')
  756. my_account2 = Account('유창래', '12345-123', '54321', '신한')
  757. my_account.income(1000000)
  758. my_account2.income(500000)
  759.  
  760. sum_money = my_account + my_account2
  761. if str(sum_money).isnumeric():
  762. print(f"두 통장의 잔고 합계는 {my_account + my_account2}원 입니다.")
  763. else:
  764. print(sum_money)
  765.  
  766. my_account.send_money(500000000, '12345', my_account2)
  767. my_account.send_money(500000, '123456', my_account2)
  768. my_account.send_money(500000, '12345', my_account2)
  769.  
  770.  
  771.  
  772. 3. Bank Class 추가하기
  773.  
  774. 1. 은행 대표번호와, 계좌 번호 생성 패턴을 입력하여 인스턴스 생성
  775. 예) shinhan = Bank(’02-1234-1234’, ‘xxx-xxxx-xxxx’)
  776. 2. 계좌 번호 생성하는 메소드를 만들어서 입력받은 패턴대로
  777. 랜덤한 숫자를 더하여 계좌번호 리턴
  778. 3. 업그레이드된 Account Class에서 인스턴스 생성시
  779. bank인스턴스도 같이 입력,
  780. bank instance의 메소드를 사용하여계좌 번호 자동생성되게 조정
  781. 4. 에러 발생시 은행 대표번호가 출력되어 문의 가능하도록 예외처리
  782.  
  783. import re
  784. from random import randrange
  785.  
  786. class Wallet:
  787. # object.__init__(self[, ...])
  788. # (__new__() 에 의해) 인스턴스가 만들어진 후에, 하지만 호출자에게 돌려주기 전에 호출된다.
  789. # 인자들은 클래스 생성자 표현으로 전달된 것들이다. 만약 베이스 클래스가 __init__() 메서드를 갖고 있다면,
  790. # 서브 클래스의 __init__() 메서드는, 있다면, 인스턴스에서 베이스 클래스가 차지하는 부분이 올바르게 초기화됨을 확실히 하기 위해 명시적으로 호출해주어야 한다;
  791. # 예를 들어: super().__init__([args...]).
  792. def __init__(self, name):
  793. self.money = 0
  794. self.owner = name
  795. print(f"{name}님 환영합니다.[__init__]")
  796.  
  797. # object.__str__(self)
  798. # str(object) 와 내장 함수 format(), print() 에 의해 호출되어 객체의 "비형식적인(informal)" 또는 보기 좋게 인쇄 가능한 문자열 표현을 계산한다.
  799. # 반환 값은 반드시 문자열 객체여야 한다.
  800. def __str__(self):
  801. return f'{self.owner}님의 지갑입니다.[__str__]'
  802.  
  803. # object.__repr__(self)
  804. # repr() 내장 함수에 의해 호출되어 객체의 "형식적인(official)" 문자열 표현을 계산한다.
  805. # 만약 가능하다면, 이것은 같은 (적절한 환경이 주어질 때) 값을 갖는 객체를 새로 만들 수 있는 올바른 파이썬 표현식처럼 보여야 한다.
  806. # 가능하지 않다면, <...쓸모있는 설명...> 형태의 문자열을 돌려줘야 한다. 반환 값은 반드시 문자열이어야 한다.
  807. # 만약 클래스가 __str__() 없이 __repr__() 만 정의한다면, __repr__() 은 그 클래스 인스턴스의 "비형식적인(informal)" 문자열 표현이 요구될 때 사용될 수 있다.
  808. def __repr__(self):
  809. return f'{self.owner}님의 지갑입니다.[__repr__]'
  810.  
  811. def print_owner_name(self):
  812. print("owner name is", self.owner)
  813.  
  814. def print_now_money(self):
  815. print(f"현재 잔액은 {self.money}원 입니다.")
  816.  
  817. def spend(self, m):
  818. if self.money < m:
  819. print("돈이 부족합니다.")
  820. self.print_now_money()
  821. else:
  822. self.money -= m
  823. print(f"{m}원을 지출했습니다.")
  824. self.print_now_money()
  825.  
  826. def income(self, m):
  827. self.money += m
  828. self.print_now_money()
  829.  
  830. def get_rand_number_string(len):
  831. x = []
  832. for _ in range(len):
  833. x.append(str(randrange(10)))
  834. return ''.join(x)
  835.  
  836. class Bank:
  837. # 정적 클래스 속성(변수), 모든 인스턴스가 공유, 클래스명이나 cls로 접근
  838. bank_instances = {} # 은행명은 중복이 없다고 보고 딕셔너리의 키값으로 사용
  839.  
  840. # 인스턴스 가 생성하는 시점, 무분별한 인스턴스 생성을 막을수 있다.
  841. def __new__(cls, name, phone, account_number_pattern):
  842. if cls.bank_instances.get(name):
  843. return cls.bank_instances[name]
  844. else:
  845. bank = super().__new__(cls)
  846. cls.bank_instances[name] = bank
  847. return bank
  848.  
  849. # 인스턴스 생성 직후 초기화
  850. def __init__(self, name, phone, account_number_pattern):
  851. self.name = re.sub('\s', '', name)
  852. self.phone = re.sub('[^0-9\\-]', '', phone)
  853. self.account_number_pattern = re.sub('[^x\\-]', '', account_number_pattern)
  854. print(f"{self.name} 정보입니다. 대표번호: {self.phone}, 계좌번호 패턴 : {self.account_number_pattern} [__init__]")
  855.  
  856. def create_account_number(self):
  857. pattern = self.account_number_pattern.split('-')
  858. x = []
  859. for p in pattern:
  860. x.append(get_rand_number_string(len(p)))
  861. return '-'.join(x)
  862.  
  863. def print_default_msg(self, msg=''):
  864. if msg:
  865. print(msg)
  866. print(f"자세한 문의사항은 {self.name} 대표번호 {self.phone} 으로 연락주십시오.")
  867.  
  868. class Account(Wallet):
  869. def __init__(self, name, password, bank):
  870. super().__init__(name)
  871. self.password = password
  872. self.bank = bank
  873. self.account_number = bank.create_account_number()
  874. print(f"{self.owner}님 계좌정보입니다. 은행: {self.bank.name}, 계좌번호: {self.account_number}, 비밀번호: {self.password} [__init__]")
  875.  
  876. def __add__(self, another):
  877. if self.owner == another.owner:
  878. return self.money + another.money
  879. else:
  880. self.bank.print_default_msg("각 계좌의 소유자가 달라서 잔액을 합산할수 없습니다.")
  881. return False
  882.  
  883. def send_money(self, money, password, to):
  884. if self.money >= money and self.password == password:
  885. if to.bank is self.bank: # 동일한 인스턴스인지 비교
  886. to.money += money
  887. self.money -= money
  888. print(f"{money}원을 {to.owner}에게 보냈습니다.")
  889. self.print_now_money()
  890. else:
  891. if self.money >= money + 500:
  892. to.money += money
  893. self.money -= money + 500
  894. print(f"{money}원을 {to.bank.name} {to.owner}에게 보냈습니다. 수수료는 500원 입니다.")
  895. self.print_now_money()
  896. else:
  897. print("돈이 부족합니다.")
  898. self.bank.print_default_msg()
  899. elif self.password == password:
  900. print("돈이 부족합니다.")
  901. self.bank.print_default_msg()
  902. else:
  903. print("비밀번호가 잘못 되었습니다.")
  904. self.bank.print_default_msg()
  905.  
  906. shinhan = Bank('신한은행', '02-1688-1788', 'xxx-xxxxx-xxxxxx')
  907. kookmin = Bank('국민은행', '02-15688-1688', 'xxxx-xxxxx-xxxxx')
  908.  
  909. my_account = Account('유창화', '12345', shinhan)
  910. my_account2 = Account('유창래', '54321', kookmin)
  911. my_account.income(1000000)
  912. my_account2.income(500000)
  913.  
  914. sum_money = my_account + my_account2
  915. if str(sum_money).isnumeric():
  916. print(f"두 통장의 잔고 합계는 {sum_money}원 입니다.")
  917.  
  918. my_account.send_money(500000000, '12345', my_account2)
  919. my_account.send_money(500000, '123456', my_account2)
  920. my_account.send_money(500000, '12345', my_account2)
  921.  
  922. print(shinhan.bank_instances)
  923. print(kookmin.bank_instances)
Add Comment
Please, Sign In to add comment