2016-11-07 3 views
0
import re, traceback, keyword 

def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 


    class type_name: 
     def __init__(self, x, y): 
      self.x = x 
      self.y = y 
      self._fields = [x,y] 
      self._mutable = False 

     def __repr__(self): 
      return 'Point(x={x},y={y})'.format(x=self.x,y=self.y) 

     def get_x(self): 
      return self.x 

     def get_y(self): 
      return self.y 

     def __getitem__(self, i): 
      if i == 0: 
       i = "x" 
      elif i == 1: 
       i = "y" 

      if i == "x": 
       return self.get_x() 
      elif i == "y": 
       return self.get_y() 
      else: 
       raise IndexError("Invalid key: {}".format(i)) 

     def __eq__(self,right): 
      if self[1] == right[1]: 
       return True 
      return False 

     def _replace(self,**kargs): 
      for key, value in kargs.iteritems(): 
       z = zip(key,value) 
      for x in z: 
       for y in self.field: 
        if x[0] == y: 
         self.x = x[1] 
        if x[0] == y: 
         self.y = x[1] 

    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name)) 
    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 

Заголовок является Защиту pnamedtuple (TYPE_NAME, field_names, изменяемые = False): пример вызова этой функцииПочему моя функция не определена?

Point = pnamedtuple('Point', ['x','y'], mutable=False) 

, что эквивалентно записи

Point = pnamedtuple('Point', 'x y') 
Point = pnamedtuple('Point', 'x,y') 

Юридическое название для типа и поля должны начинаться с буквы, за которой могут следовать 0 или более букв, цифр или символов подчеркивания

field_names должно быть список юридических имен, таких как ['x', 'y'] или 'x y', или 'x, y'

p = Point (1,2) writing p.get_x() или p [ 0]), или p ['x'] возвращает результат 1

new_origin = origin._replace (y = 5), затем печать (origin, new_origin) будет отображаться как точка (x = 0, y = 0) Точка (x = 0, y = 5)

Однако, когда я запускаю эту функцию, она показывает, что все не определено. Я добавил код bsc.txt ниже, это немного долго:

6 # Test pnamedtuple (as pnt) 
7 *Error: Triple1 = pnt('Triple1', 'a b c') raised exception NameError: name 'class_definition' is not defined 
8 *Error: print(Triple1.source_code) raised exception NameError: name 'Triple1' is not defined 
9 *Error: Triple2 = pnt('Triple2', 'a, b, c') raised exception NameError: name 'class_definition' is not defined 
10 *Error: Triple3 = pnt('Triple3', ['a','b','c']) raised exception NameError: name 'class_definition' is not defined 
11 *Error: Triple_Bad = pnt(1, 'a b c') raised wrong exception(NameError) should be from list: SyntaxError 
12 *Error: Triple_Bad = pnt('Triple_Bad', {'a','b','c'}) raised wrong exception(NameError) should be from list: SyntaxError 
13 *Error: Triple_Bad = pnt('3', 'a b c') raised wrong exception(NameError) should be from list: SyntaxError 
14 *Error: Triple_Bad = pnt('Triple_Bad', 'a 3 c') raised wrong exception(NameError) should be from list: SyntaxError 
15 *Error: Triple_Bad = pnt('Triple_Bad', 'a b if') raised wrong exception(NameError) should be from list: SyntaxError 
16 *Error: Triple_Bad = pnt('Triple_Bad', '_a _b _c') raised wrong exception(NameError) should be from list: SyntaxError 
17 *Error: Triple_OK = pnt('Triple_OK', 'a17 b__1 c__2') raised exception NameError: name 'class_definition' is not defined 
18 # Test init/repr 
19 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
20 *Error: repr(t1) raised exception NameError: name 't1' is not defined 
21 *Error: t2 = Triple2(1,2,3) raised exception NameError: name 'Triple2' is not defined 
22 *Error: repr(t2) raised exception NameError: name 't2' is not defined 
23 *Error: t3 = Triple3(1,2,3) raised exception NameError: name 'Triple3' is not defined 
24 *Error: repr(t3) raised exception NameError: name 't3' is not defined 
25 *Error: t3 = Triple3(c=3,b=2,a=1) raised exception NameError: name 'Triple3' is not defined 
26 *Error: repr(t3) raised exception NameError: name 't3' is not defined 
27 *Error: tok= Triple_OK(c__2=3,b__1=2,a17=1) raised exception NameError: name 'Triple_OK' is not defined 
28 *Error: repr(tok) raised exception NameError: name 'tok' is not defined 
29 *Error: t1.a raised exception NameError: name 't1' is not defined 
30 *Error: t1.b raised exception NameError: name 't1' is not defined 
31 *Error: t1.c raised exception NameError: name 't1' is not defined 
32 *Error: t1.d raised wrong exception(NameError) should be from list: AttributeError 
33 # Test get_ methods 
34 *Error: t1.get_a() raised exception NameError: name 't1' is not defined 
35 *Error: t1.get_b() raised exception NameError: name 't1' is not defined 
36 *Error: t1.get_c() raised exception NameError: name 't1' is not defined 
37 *Error: t1.get_d() raised wrong exception(NameError) should be from list: AttributeError 
38 *Error: l = [Triple1(a=1,b=2,c=3),Triple1(b=1,c=2,a=3),Triple1(c=1,a=2,b=3)] raised exception NameError: name 'Triple1' is not defined 
39 *Error: l.sort(key=Triple1.get_a) raised exception NameError: name 'l' is not defined 
40 *Error: l raised exception NameError: name 'l' is not defined 
41 # Test __getitem__ functions 
42 *Error: t1[0] raised exception NameError: name 't1' is not defined 
43 *Error: t1[1] raised exception NameError: name 't1' is not defined 
44 *Error: t1[2] raised exception NameError: name 't1' is not defined 
45 *Error: t1['a'] raised exception NameError: name 't1' is not defined 
46 *Error: t1['b'] raised exception NameError: name 't1' is not defined 
47 *Error: t1['c'] raised exception NameError: name 't1' is not defined 
48 *Error: t1[4] raised wrong exception(NameError) should be from list: IndexError 
49 *Error: t1['d'] raised wrong exception(NameError) should be from list: IndexError 
50 *Error: t1[3.2] raised wrong exception(NameError) should be from list: IndexError 
51 # Test == 
52 *Error: t1 == t1 raised exception NameError: name 't1' is not defined 
53 *Error: t1 == t2 raised exception NameError: name 't1' is not defined 
54 *Error: t1 == Triple1(a=1,b=2,c=3) raised exception NameError: name 't1' is not defined 
55 *Error: t1 == Triple1(a=1,b=1,c=3) raised exception NameError: name 't1' is not defined 
56 # Test replace (not mutable) 
57 *Error: t1._replace(a=2) raised exception; unevaluated: Triple1(2,2,3) 
58 *Error: t1._replace(a=2,c=2) raised exception; unevaluated: Triple1(2,2,2) 
59 *Error: t1._replace(a=2,c=2,d=2) raised wrong exception(NameError) should be from list: TypeError 
60 *Error: t1 raised exception; unevaluated: Triple1(a=1,b=2,c=3) 
61 # Test _replace (mutable) 
62 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=True) raised exception NameError: name 'class_definition' is not defined 
63 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
64 *Error: t1._replace(a=2,c=2) raised exception NameError: name 't1' is not defined 
65 *Error: t1 raised exception; unevaluated: Triple1(a=2,b=2,c=2) 
66 # Test Extra Credit (prohibit mutation if immutable) 
67 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=False) raised exception NameError: name 'class_definition' is not defined 
68 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
69 *Error: t1.a = 2 raised wrong exception(NameError) should be from list: AttributeError 
70 *Error: Triple1 = pnt('Triple1', 'a b c',mutable=True) raised exception NameError: name 'class_definition' is not defined 
71 *Error: t1 = Triple1(1,2,3) raised exception NameError: name 'Triple1' is not defined 
72 *Error: t1.a = 2 raised exception NameError: name 't1' is not defined 
73 *Error: t1 raised exception; unevaluated: Triple1(2,2,3) 

может someon сказать мне, почему я получаю все эти ошибки? Это потому, что что-то не так с моей машиной? Может кто-нибудь сказать мне, как это исправить? большое спасибо.

это базовый код, который я был предоставлен:

import re, traceback, keyword 

def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 

# put your code here 
# bind class_definition (used below) to the string constructed for the class 


# For initial debugging, always show the source code of the class 
#show_listing(class_definition) 

# Execute the class_definition string in a local namespace, binding the 
# name source_code in its dictionary to the class_defintion; return the 
# class object created; if there is a syntax error, list the class and 
# also show the error 
    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name)) 
    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 
+1

Почему вы определяете класс внутри метода? –

+1

Да, это, вероятно, дает вам 73 ошибки ... не делайте этого – Jakub

+0

Я думал, что это требование, это не так? – zeyuxie

ответ

0

Я не уверен, что ваше определение класса или где вы получите его от, это было бы очень полезно, если вы разместите его. Я полагаю, что у вас есть исходный код, лежащий вокруг, и предполагается, что он будет завершен в класс, который наследует базовый класс в вашей функции.

Я вызываю базовый класс irrelevant, потому что имя буквально не имеет значения, оно будет разрешено только в пределах области действия, что является тем, что говорят комментаторы. В вашем случае тот факт, что он не может быть разрешен во внешней сфере, не только приемлем, но и предназначен.

Этот код будет делать то, что вы ожидаете, что я предполагаю:

import re, traceback, keyword 


def pnamedtuple(type_name, field_names, mutable=False): 
    def show_listing(s): 
     for i, l in enumerate(s.split('\n'), 1): 
      print('{num: >4} {txt}'.format(num= i, txt= l.rstrip())) 


    class irrelevant: 
     def __init__(self, x, y): 
      self.x = x 
      self.y = y 
      self._fields = [x,y] 
      self._mutable = False 

     def __repr__(self): 
      return 'Point(x={x},y={y})'.format(x=self.x,y=self.y) 

     def get_x(self): 
      return self.x 

     def get_y(self): 
      return self.y 

     def __getitem__(self, i): 
      if i == 0: 
       i = "x" 
      elif i == 1: 
       i = "y" 

      if i == "x": 
       return self.get_x() 
      elif i == "y": 
       return self.get_y() 
      else: 
       raise IndexError("Invalid key: {}".format(i)) 

     def __eq__(self,right): 
      if self[1] == right[1]: 
       return True 
      return False 

     def _replace(self,**kargs): 
      for key, value in kargs.iteritems(): 
       z = zip(key,value) 
      for x in z: 
       for y in self.field: 
        if x[0] == y: 
         self.x = x[1] 
        if x[0] == y: 
         self.y = x[1] 

    name_space = dict(__name__='pnamedtuple_{type_name}'.format(type_name= type_name),irrelevant=irrelevant) 
    class_definition = "class Point(irrelevant):\n pass" 

    try: 
     exec(class_definition,name_space) 
     name_space[type_name].source_code = class_definition 
    except(SyntaxError, TypeError): 
     show_listing(class_definition) 
     traceback.print_exc() 
    return name_space[type_name] 

Point = pnamedtuple('Point', ['x','y'], mutable=False) 
p = Point(1,2) 
print(p.get_x()) 

Хитрость заключается в том, чтобы выполнить свой код во время прохождения BaseClass в вашем контексте. В зависимости от исходного содержимого class_definition может потребоваться изменить код.

Блестящий вопрос, где вы получили это задание?

+0

Привет, Это на самом деле мое домашнее задание, это то, что класс будет делать: – zeyuxie

+0

Напишите функцию с именем pnamedtuple, которая передается информация об именованном кортеже: он возвращает ссылку на объект класса, из которого мы можем построить экземпляры указанного именованного кортежа. Мы могли бы использовать этот класс следующим образом: from pcollections import pnamedtuple Point = pnamedtuple ('Point', 'x y') p = Точка (0,0) – zeyuxie

+0

также, я не думаю, что вы можете изменить базовый код, он по-прежнему показывается undefined после того, как я изменил код, который вы предоставили. – zeyuxie

Смежные вопросы