왜 파이썬 클래스에서 __init__를 사용합니까?
수업 초기화를 이해하는 데 문제가 있습니다.
요점은 무엇이며 어떻게 포함해야하는지 어떻게 알 수 있습니까? 수업에서 쓰는 것은 다른 유형의 사고와 함수를 만드는 것이 필요합니까 (함께 함수를 만든 다음 클래스에서 랩하여 재사용 할 수 있다고 생각했습니다. 작동합니까?)
예를 들면 다음과 같습니다.
class crawler:
# Initialize the crawler with the name of database
def __init__(self,dbname):
self.con=sqlite.connect(dbname)
def __del__(self):
self.con.close()
def dbcommit(self):
self.con.commit()
또는 다른 코드 샘플 :
class bicluster:
def __init__(self,vec,left=None,right=None,distance=0.0,id=None):
self.left=left
self.right=right
self.vec=vec
self.id=id
self.distance=distance
__init__
다른 사람들의 코드를 읽으려고 할 때 너무 많은 클래스가 있지만 클래스를 만드는 논리를 이해하지 못합니다.
당신이 쓴 것에 의해, 당신은 중요한 이해의 부분, 즉 클래스와 객체의 차이점이 빠져 있습니다. __init__
클래스를 초기화하지 않고 클래스 또는 객체의 인스턴스를 초기화합니다. 각 개는 색깔이 있지만 개로서 개는 그렇지 않습니다. 각 개는 발이 4 개 이하이지만 개는 그렇지 않습니다. 클래스는 객체의 개념입니다. Fido와 Spot을 보면 그들의 유사성과 그들의 개성을 인식합니다. 그것이 수업입니다.
당신이 말할 때
class Dog:
def __init__(self, legs, colour):
self.legs = legs
self.colour = colour
fido = Dog(4, "brown")
spot = Dog(3, "mostly yellow")
당신이 말하는 것처럼, Fido는 다리가 4 개인 갈색 개이며 Spot은 약간의 주름이 있고 대부분 노란색입니다. 이 __init__
함수를 생성자 또는 이니셜 라이저라고하며 클래스의 새 인스턴스를 만들 때 자동으로 호출됩니다. 해당 함수 내에서 새로 작성된 오브젝트가 매개 변수에 지정됩니다 self
. 표기법 self.legs
은 legs
변수에서 객체 의 속성 self
입니다. 속성은 일종의 변수이지만 객체의 상태 또는 객체에 사용할 수있는 특정 작업 (기능)을 설명합니다.
그러나, 당신은 colour
doghood 자체를 위해 설정하지 않았 음을 주목 하십시오-그것은 추상적 인 개념입니다. 클래스에는 의미가있는 속성이 있습니다. 예를 들어, population_size
Fido는 항상 하나이므로 Fido를 계산하는 것은 의미가 없습니다. 개를 세는 것이 합리적입니다. 세계에 2 억 마리의 개가 있다고합시다. Dog 클래스의 속성입니다. Fido는 2 억의 숫자와 관련이 없으며 Spot도 아닙니다. 있다 "인스턴스 속성"반대로 그것은하는 "클래스 속성"이라고 colour
또는 legs
위.
이제 덜 개과 더 많은 프로그래밍 관련이 있습니다. 아래에 글을 쓸 때, 물건을 추가하는 수업은 합리적이지 않습니다. 수업은 무엇입니까? 파이썬의 클래스는 비슷한 방식으로 작동하는 서로 다른 데이터의 모음으로 구성됩니다. 개 클래스는 Fido와 Spot 및 199999999998 다른 동물로 구성되며, 모두 가로등 기둥에서 오줌을 싸고 있습니다. 물건을 추가하는 클래스는 무엇으로 구성됩니까? 그들 고유의 데이터는 무엇입니까? 그리고 그들은 어떤 행동을 공유합니까?
그러나 숫자는 ... 더 흥미로운 주제입니다. 말해봐, 정수 개보다 훨씬 더 많이 있습니다. 파이썬에는 이미 정수가 있다는 것을 알고 있습니다. 그러나 속임수를 쓰고 "파이썬 정수를 사용하여"다시 "구현"합시다.
따라서 정수는 클래스입니다. 그것들은 약간의 데이터 (값)와 행동 (“이 숫자에 나를 추가”)을 가지고 있습니다. 이것을 보여 주자 :
class MyInteger:
def __init__(self, newvalue)
# imagine self as an index card.
# under the heading of "value", we will write
# the contents of the variable newvalue.
self.value = newvalue
def add(self, other):
# when an integer wants to add itself to another integer,
# we'll take their values and add them together,
# then make a new integer with the result value.
return MyInteger(self.value + other.value)
three = MyInteger(3)
# three now contains an object of class MyInteger
# three.value is now 3
five = MyInteger(5)
# five now contains an object of class MyInteger
# five.value is now 5
eight = three.add(five)
# here, we invoked the three's behaviour of adding another integer
# now, eight.value is three.value + five.value = 3 + 5 = 8
print eight.value
# ==> 8
이것은 약간 깨지기 other
쉽지만 (우리는 MyInteger가 될 것이라고 가정 합니다), 지금은 무시할 것입니다. 실제 코드에서는 그렇지 않습니다. 우리는 그것을 확인하기 위해 그것을 테스트하고, 아마도 그것을 강요 할 것입니다 ( "당신은 정수가 아니십니까? Golly에 의해 10 나노 초가되어 하나가됩니다! 9 ... 8 ....")
분수를 정의 할 수도 있습니다. 분수는 또한 자신을 추가하는 방법도 알고 있습니다.
class MyFraction:
def __init__(self, newnumerator, newdenominator)
self.numerator = newnumerator
self.denominator = newdenominator
# because every fraction is described by these two things
def add(self, other):
newdenominator = self.denominator * other.denominator
newnumerator = self.numerator * other.denominator + self.denominator * other.numerator
return MyFraction(newnumerator, newdenominator)
정수보다 훨씬 더 많은 분수가 있습니다 (실제로는 아니지만 컴퓨터는 그것을 알지 못합니다). 두 가지를 만들어 보자.
half = MyFraction(1, 2)
third = MyFraction(1, 3)
five_sixths = half.add(third)
print five_sixths.numerator
# ==> 5
print five_sixths.denominator
# ==> 6
당신은 실제로 여기에 아무것도 선언하지 않습니다. 속성은 새로운 종류의 변수와 같습니다. 정규 변수에는 하나의 값만 있습니다. 당신이 쓴다고 말해 보자 colour = "grey"
. 당신은라는 이름의 또 다른 변수가 가질 수 없습니다 colour
입니다 "fuchsia"
하지 코드에 같은 장소에를 -.
배열은 어느 정도 해결합니다. 이라고 말하면 colour = ["grey", "fuchsia"]
변수에 두 가지 색상을 쌓았지만 위치 (이 경우 0 또는 1)로 구분합니다.
속성은 객체에 바인딩 된 변수입니다. 배열과 마찬가지로 colour
, 다른 개에 대해 많은 변수를 가질 수 있습니다 . 따라서 fido.colour
하나의 변수이지만 spot.colour
다른 변수 입니다. 첫 번째 변수는 변수 내의 객체에 바인딩됩니다 fido
. 두 번째 spot
. 이제 Dog(4, "brown")
또는 을 호출 three.add(five)
하면 항상 보이지 않는 매개 변수가 있으며이 매개 변수는 매개 변수 목록의 앞에 매달려있는 추가 매개 변수에 지정됩니다. 일반적으로이라고 self
하며 점 앞에서 객체의 값을 가져옵니다. 따라서 개 __init__
(생성자) self
안에서 새 개가 무엇이든 될 것입니다. 내 MyInteger
S ' add
, self
변수의 개체에 바인딩됩니다 three
. 그러므로,three.value
외부 같은 변수 것 add
같이 self.value
이내 add
.
이라고하면 다른 이름 the_mangy_one = fido
으로 알려진 개체를 참조하기 시작합니다 fido
. 이제 fido.colour
부터는와 정확히 동일한 변수 the_mangy_one.colour
입니다.
그래서 내부의 것들 __init__
. 당신은 그것들을 개의 출생 증명서에있는 것을 지적하는 것으로 생각할 수 있습니다. colour
그 자체로는 임의의 변수이며 무엇이든 포함 할 수 있습니다. fido.colour
또는 self.colour
Dog의 신원 확인서에있는 양식 필드와 같습니다. 그리고 __init__
점원이 처음으로 그것을 채우고 있습니다.
더 명확 해?
편집 : 아래 주석에서 확장 :
당신은 객체 의 목록을 의미 합니까?
우선, fido
실제로는 객체가 아닙니다. 그것은 현재 당신이 말할 때와 같은 개체를 포함하는 변수이며 x = 5
, x
현재 5 번을 포함하는 변수입니다. 나중에 마음이 바뀌면 fido = Cat(4, "pleasing")
(클래스를 만든 한 Cat
) fido
고양이 개체를 "포함"할 수 있습니다. 그렇게 fido = x
하면 동물 개체가 아닌 숫자 5를 포함하게됩니다.
클래스는 추적하기 위해 코드를 구체적으로 작성하지 않으면 인스턴스 자체를 알지 못합니다. 예를 들어 :
class Cat:
census = [] #define census array
def __init__(self, legs, colour):
self.colour = colour
self.legs = legs
Cat.census.append(self)
여기 census
클래스의 Cat
클래스 레벨 속성이 있습니다.
fluffy = Cat(4, "white")
spark = Cat(4, "fiery")
Cat.census
# ==> [<__main__.Cat instance at 0x108982cb0>, <__main__.Cat instance at 0x108982e18>]
# or something like that
당신은 얻을 수 없습니다 [fluffy, sparky]
. 그것들은 단지 변수 이름입니다. 고양이 스스로 이름을 가지려면 이름에 대해 별도의 속성을 만든 다음 __str__
이 이름을 반환 하도록 메서드를 재정의해야합니다 . 이 방법의 (즉, 클래스 바인딩 기능, 그냥 같은 add
나 __init__
) 목적은 당신이 그것을 밖으로 인쇄 할 때와 같은 문자열로 개체를 변환하는 방법을 설명하는 것입니다.
내 5 센트를 Amadan 의 철저한 설명에 공헌 합니다.
여기서 클래스는 추상적 인 방식으로 "유형"에 대한 설명입니다. 살아 숨쉬는 것. 객체 지향 세계에는 거의 모든 것의 본질이라고 부를 수있는 주요 아이디어가 있습니다. 그들은:
- 캡슐화 (이에 대해 자세히 설명하지는 않음)
- 계승
- 다형성
Objects have one, or more characteristics (= Attributes) and behaviors (= Methods). The behavior mostly depends on the characteristics. Classes define what the behavior should accomplish in a general way, but as long as the class is not realized (instantiated) as an object it remains an abstract concept of a possibility. Let me illustrate with the help of "inheritance" and "polymorphism".
class Human:
gender
nationality
favorite_drink
core_characteristic
favorite_beverage
name
age
def love
def drink
def laugh
def do_your_special_thing
class Americans(Humans)
def drink(beverage):
if beverage != favorite_drink: print "You call that a drink?"
else: print "Great!"
class French(Humans)
def drink(beverage, cheese):
if beverage == favourite_drink and cheese == None: print "No cheese?"
elif beverage != favourite_drink and cheese == None: print "Révolution!"
class Brazilian(Humans)
def do_your_special_thing
win_every_football_world_cup()
class Germans(Humans)
def drink(beverage):
if favorite_drink != beverage: print "I need more beer"
else: print "Lecker!"
class HighSchoolStudent(Americans):
def __init__(self, name, age):
self.name = name
self.age = age
jeff = HighSchoolStudent(name, age):
hans = Germans()
ronaldo = Brazilian()
amelie = French()
for friends in [jeff, hans, ronaldo]:
friends.laugh()
friends.drink("cola")
friends.do_your_special_thing()
print amelie.love(jeff)
>>> True
print ronaldo.love(hans)
>>> False
Some characteristics define human beings. But every nationality differs somewhat. So "national-types" are kinda Humans with extras. "Americans" are a type of "Humans " and inherit some abstract characteristics and behavior from the human type (base-class) : that's inheritance. So all Humans can laugh and drink, therefore all child-classes can also! Inheritance (2).
But because they are all of the same kind (Type/base-class : Humans) you can exchange them sometimes: see the for-loop at the end. But they will expose an individual characteristic, and thats Polymorphism (3).
So each human has a favorite_drink, but every nationality tend towards a special kind of drink. If you subclass a nationality from the type of Humans you can overwrite the inherited behavior as I have demonstrated above with the drink()
Method. But that's still at the class-level and because of this it's still a generalization.
hans = German(favorite_drink = "Cola")
instantiates the class German and I "changed" a default characteristic at the beginning. (But if you call hans.drink('Milk') he would still print "I need more beer" - an obvious bug ... or maybe that's what i would call a feature if i would be a Employee of a bigger Company. ;-)! )
The characteristic of a type e.g. Germans (hans) are usually defined through the constructor (in python : __init__
) at the moment of the instantiation. This is the point where you define a class to become an object. You could say breath life into an abstract concept (class) by filling it with individual characteristics and becoming an object.
But because every object is an instance of a class they share all some basic characteristic-types and some behavior. This is a major advantage of the object-orientated concept.
To protect the characteristics of each object you encapsulate them - means you try to couple behavior and characteristic and make it hard to manipulate it from outside the object. That's Encapsulation (1)
It is just to initialize the instance's variables.
E.g. create a crawler
instance with a specific database name (from your example above).
It seems like you need to use __init__
in Python if you want to correctly initialize mutable attributes of your instances.
See the following example:
>>> class EvilTest(object):
... attr = []
...
>>> evil_test1 = EvilTest()
>>> evil_test2 = EvilTest()
>>> evil_test1.attr.append('strange')
>>>
>>> print "This is evil:", evil_test1.attr, evil_test2.attr
This is evil: ['strange'] ['strange']
>>>
>>>
>>> class GoodTest(object):
... def __init__(self):
... self.attr = []
...
>>> good_test1 = GoodTest()
>>> good_test2 = GoodTest()
>>> good_test1.attr.append('strange')
>>>
>>> print "This is good:", good_test1.attr, good_test2.attr
This is good: ['strange'] []
This is quite different in Java where each attribute is automatically initialized with a new value:
import java.util.ArrayList;
import java.lang.String;
class SimpleTest
{
public ArrayList<String> attr = new ArrayList<String>();
}
class Main
{
public static void main(String [] args)
{
SimpleTest t1 = new SimpleTest();
SimpleTest t2 = new SimpleTest();
t1.attr.add("strange");
System.out.println(t1.attr + " " + t2.attr);
}
}
produces an output we intuitively expect:
[strange] []
But if you declare attr
as static
, it will act like Python:
[strange] [strange]
Following with your car example: when you get a car, you just don't get a random car, I mean, you choose the color, the brand, number of seats, etc. And some stuff is also "initialize" without you choosing for it, like number of wheels or registration number.
class Car:
def __init__(self, color, brand, number_of_seats):
self.color = color
self.brand = brand
self.number_of_seats = number_of_seats
self.number_of_wheels = 4
self.registration_number = GenerateRegistrationNumber()
So, in the __init__
method you defining the attributes of the instance you're creating. So, if we want a blue Renault car, for 2 people, we would initialize or instance of Car
like:
my_car = Car('blue', 'Renault', 2)
This way, we are creating an instance of the Car
class. The __init__
is the one that is handling our specific attributes (like color
or brand
) and its generating the other attributes, like registration_number
.
- More about classes in Python
- More about the
__init__
method
Classes are objects with attributes (state, characteristic) and methods (functions, capacities) that are specific for that object (like the white color and fly powers, respectively, for a duck).
When you create an instance of a class, you can give it some initial personality (state or character like the name and the color of her dress for a newborn). You do this with __init__
.
Basically __init__
sets the instance characteristics automatically when you call instance = MyClass(some_individual_traits)
.
The __init__
function is setting up all the member variables in the class. So once your bicluster is created you can access the member and get a value back:
mycluster = bicluster(...actual values go here...)
mycluster.left # returns the value passed in as 'left'
Check out the Python Docs for some info. You'll want to pick up an book on OO concepts to continue learning.
class Dog(object):
# Class Object Attribute
species = 'mammal'
def __init__(self,breed,name):
self.breed = breed
self.name = name
In above example we use species as a global since it will be always same(Kind of constant you can say). when you call __init__
method then all the variable inside __init__
will be initiated(eg:breed,name).
class Dog(object):
a = '12'
def __init__(self,breed,name,a):
self.breed = breed
self.name = name
self.a= a
if you print the above example by calling below like this
Dog.a
12
Dog('Lab','Sam','10')
Dog.a
10
That means it will be only initialized during object creation. so anything which you want to declare as constant make it as global and anything which changes use __init__
참고URL : https://stackoverflow.com/questions/8609153/why-do-we-use-init-in-python-classes
'program tip' 카테고리의 다른 글
프로그래밍 방식으로 모카에서 테스트를 건너 뛰는 방법은 무엇입니까? (0) | 2020.07.26 |
---|---|
C ++에서 "int & foo ()"는 무엇을 의미합니까? (0) | 2020.07.26 |
쉘을 사용하여 PostgreSQL에 데이터베이스가 있는지 확인하십시오. (0) | 2020.07.26 |
Rails에서 다른 형식의 일부를 어떻게 렌더링합니까? (0) | 2020.07.26 |
쉘 스크립트의 연관 배열 (0) | 2020.07.26 |