#python #python-2.7
#python #python-2.7
Вопрос:
Я изучаю Python (мое образование — C, C ).
В следующем коде из tutorialspoint.com:
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount = 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
(1) Моя путаница заключается в переменных экземпляра ‘self.name «, самооценка.зарплата». Я понимаю, что переменные в Pythons не нуждаются в явном объявлении, в отличие от C, но тогда как эти переменные могут использоваться в методе ‘displayEmployee’, разве у них нет собственной локальной области видимости, которая является методом конструктора ‘_ init _’? Кроме того, эта переменная ‘self’ является объектом для создаваемого класса — так что это будет означать, что объявление класса в Python также создает объект этого класса (поэтому никаких виртуальных классов, как в C ) одновременно?
(2) Мой второй (менее важный) вопрос, в приведенном выше коде, почему случайно размещенные строки «Это создаст первый объект класса Employee» и «Это создаст второй объект класса Employee», не показывают ошибку? Насколько я знаю, комментарии должны начинаться с # или «‘? Или строки также рассматриваются как пробелы в Python?
Комментарии:
1. Подождите, вы используете python 2?
2. Да, sry должен был упомянуть, что
3. Это конец срока службы, поэтому, вероятно , не стоит изучать / использовать намного дольше. Хотя у Python3 был бы тот же ответ
4.
self
какthis
в C5.
self.name
это не переменная, это выражение, которое ищет атрибутname
объекта, заданныйself
.self
Для использования этого выражения должна быть только область видимости, и фактически это один из параметров для каждого из методов, которые используют его здесь.
Ответ №1:
- Создание объекта (т.е.
Emplyee()
Вызывает__init__()
метод, инициализатор). Все методы, которые затем имеютself
аргумент, используют экземпляр этого объекта для работы. Это означает, что эти методы будут иметь доступ кself
переменным этого объекта. Это означает, что статические методы не имеют к этому доступа, и почему доступ к этим переменным экземпляра не приводит к ошибке. В качестве примера, это приведет к ошибке:
class Employee:
def __init__(self):
self.variable = 123
@staticmethod # Decorator to indicate this method should not accept 'self'
def static_method():
print(self.variable)
Потому что метод static_method()
не работает с инициализирующим экземпляром Employee
объекта.
- Строки, как и любая другая неназначенная переменная, будут интерпретироваться, а затем отбрасываться. Например, следующее:
123
"test"
[1, 2]
Все они ничего не делают, но, учитывая, что они являются технически корректными утверждениями, они не приводят к ошибкам. Вы часто будете видеть этот тип инструкций в docstrings, например:
"""
Long string goes here.
"""
Комментарии:
1. Стоит упомянуть строки в тройных кавычках для документации.
2. Итак, переменные self — все ли они обязательно определены в init, или некоторые другие методы также могут определять переменные для self?
3. Инициализатор — это инициализатор. Новый — это конструктор. New должен каждый раз возвращать новый экземпляр, init можно использовать для повторной инициализации столько раз, сколько вы хотите.
type.__call__
это то, что на самом деле гарантирует, что оба будут вызваны, когда вы это сделаетеEmployee()
4. Переменные экземпляра не обязательно определять в конструкторе класса / объекта. Лучше всего, чтобы вы могли получить лучшее «представление» о том, какие методы экземпляра существуют в классе, просто взглянув на конструктор, и вы избежите потенциального столкновения с an
AttributeError
при ссылке на переменные экземпляра, которые еще не определены. Однако любой метод экземпляра может создавать новые переменные экземпляра, если вы решите это сделать.5. Отличная мысль @MadPhysicist — исправлено. @Kaind, (i) Это правильно. Попытка получить доступ к переменной экземпляра (атрибуту), которая не существует
AttributeError
, вызоветdisplayCount()
, который присваивает / создает эту переменную, затем остановит это поведение (в вашем случае). (ii) В этом нет необходимости, но использованиеself
чаще встречается, чем нет. Подумайте о классе, который имеет некоторую функцию, которая не взаимодействует ни с одним из атрибутов / переменных экземпляра этого класса, вы можете сделать этот метод статическим и удалить вself
качестве первого аргумента.