2010-04-20 5 views
7

Я преподаю мой сам питон, и я переводил некоторые примеры кода в этупитона переменной сфера

class Student(object): 
    def __init__(self, name, a,b,c): 
     self.name = name 
     self.a = a 
     self.b = b 
     self.c = c 

    def average(self): 
     return (a+b+c)/3.0 

что довольно много мое предназначено определение класса

Позже в главном методе я создаю экземпляр и назвать его a

if __name__ == "__main__" : 
    a = Student("Oscar", 10, 10, 10) 

Вот как я узнаю, что переменная a объявлена ​​в main доступна метод average и чтобы этот метод работал, я должен ввести self.a + self.b + self.c вместо

В чем причина этого?

Я нашел родственные вопросы, но я не знаю, если они находятся в одних и тех же

+2

В качестве побочного примечания всегда наследуйте 'object', так что вы используете * классы нового стиля *, то есть' class Student (object): '. –

+0

@Mike Subclassing 'object' в Python 2.x - хорошая практика, но в Python 3 это не нужно, так как все классы являются« новыми ». Я понимаю, что принятие Python 3 является плохим, и если предположить, что OP использует Python 2.x, это разумно, но в какой-то день я надеюсь, что это будет плохое предположение. – gotgenes

ответ

9

Barenames (как a, b, c) являются всегда локализованные или локальные (за исключением вложенных функций, которые нигде не находятся в вашем коде). Обоснование заключается в том, что добавление дополнительных областей без лишних затрат осложняет ситуацию: например, если в вашем self.a = a barename a может быть ограниченным, чтобы означать то, что вам кажется нужным (эквивалентно self.a), тогда само присваивание было бы бессмысленным (присвоение имени для себя), поэтому вам понадобятся дополнительные сложные правила.

Просто используя квалифицированные имена (например, self.a), когда вы хотите, чтобы что-то отличное от простого, простого и оптимизированного поведения барменов, на сегодняшний день является самым простым подходом - совершенно выполнимым, без сложных правил и позволяет компилятору оптимизировать (так как, например, область действия barename всегда лексически определена, не зависит от динамически изменяющихся характеристик окружающей среды). Таким образом, помимо, возможно, ностальгии по другому языку с более сложными правилами охвата, нет никакого смысла усложнять семантику барных имен.

+0

Я почти понял ... что я «То, что произойдет, если произойдет, если я объявлю локальный« а »в моем методе ... (я думаю, я найду его, набрав немного). BRB – OscarRyz

+0

Я вернулся .. поэтому, когда я объявить локальную переменную 'a', она имеет приоритет над глобальной переменной' a' (как и ожидалось). Я предполагаю, что единственный способ использовать эту глобальную переменную - не называть мой локальный то же самое, не так ли? – OscarRyz

+0

@Oscar Reyes: Если вы хотите использовать такую ​​переменную, передайте ее как параметр в метод, например. 'student.average (a)' где 'def average (self, para)'. Чем вы можете использовать 'para' внутри вашего метода, и он будет иметь значение, которое вы предоставляете при вызове метода. Но это не специфичный для Python, это так на любом языке программирования ... –

-1

Все переменные экземпляра следует назвать использование собственной личности

+1

Это неудачное начало SO 'карьеры' :) – KevinDTimm

+0

, чтобы добавить, хотя, я думаю, что ваш ответ, возможно, был правильным, настолько расплывчатым (и неполным), что требовалось downvote – KevinDTimm

2

Существует несколько причин, хотя главная из них - это Дзен Питона: «Явный лучше, чем неявный». На языке, подобном C++, метод класса всегда имеет неявный аргумент this, который выталкивается в стек каждый раз, когда вызывается метод. В этом случае, когда существует переменная экземпляра b, а также глобальная переменная b, пользователь может просто ссылаться на b, ссылаясь на один, не понимая, что будет использоваться другой. Таким образом, Python заставляет вас проявлять ясность в своей области, чтобы избежать путаницы.

С учетом сказанного, есть и другие причины. Например, я могу определить функцию вне класса, а затем прикрепить ее к классу во время выполнения. Например:

def log(self): 
    print "some library function requires all objects to have a log method" 
    print "unfortunately we're using the Student class, which doesn't have one" 
    print "this class is defined in a separate library, so we can't add the method" 
    print "fortunately, we can just add the method dynamically at runtime" 

Student.log = log 

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

Вот еще более сложный пример; Предположим, мы хотим определить класс внутри другого класса, например, для целей модульного тестирования:

class SomeUnitTests(TestCase): 
    def test_something(self): 
     class SomeMockObject(SomeActualObject): 
      def foo(self2): 
       self.assertEqual(self2.x, SOME_CONSTANT) 

     some_lib.do_something_with(SomeMockObject) 

Здесь наличие явного самости (который мы можем назвать то, что мы хотим, это не должно быть self) позволяет различать self внутреннего и внешнего классов. Опять же, это не то, что я часто делаю, но когда я это делаю, это невероятно полезно.

+2

Имеют смысл, кроме явного глобального (или это?) – OscarRyz

+0

Существует глобальное ключевое слово, которое можно использовать для объявления переменной внутри функции, которая должна иметь глобальную область: http://docs.python.org/ выпуск/2.5.2/исх/global.html –

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